On Thursday, 28. June 2007, Stefano Cavallari wrote:
>
> drivers/acpi/asus_acpi.c is older, and is (maybe) more stable and more
> supported by some apps (kde shows brightness changes etc...)
> drivers/misc/asus-laptop.c is newer and works better for some (if not
> all) hardware. It supports the new led class interface.
>
> HTH.
Yes
asus_acpi.c is just waiting to become obsolete.
The real reason for this silly question is, that my G1S laptop (and maybe some
other ASUS' notebooks too)
reports the fanspeed (it's wrapped into ACPI's temperature reading thing, but
you probably know this already).
And I really wanted it to read it in userspace. So, here's a small hack
(2.6.22-rc5-git7) that adds the necessary hwmon sysfs stuff :-) ..
So, please test & report. (see /sys/devices/platform/asus_laptop.0/fan1_input !
)
If this thing is useful after all, I will write a better patch and a
signed-off-line.
Thanks,
Chr.
--- a/drivers/misc/asus-laptop.c 2007-06-23 00:14:43.159734759 +0200
+++ b/drivers/misc/asus-laptop.c 2007-06-28 22:45:16.153507721 +0200
@@ -43,6 +43,8 @@
#include <linux/backlight.h>
#include <linux/fb.h>
#include <linux/leds.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
#include <linux/platform_device.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
@@ -54,7 +56,7 @@
#define ASUS_HOTK_CLASS "hotkey"
#define ASUS_HOTK_DEVICE_NAME "Hotkey"
#define ASUS_HOTK_HID "ATK0100"
-#define ASUS_HOTK_FILE "asus-laptop"
+#define ASUS_HOTK_FILE "asus_laptop"
#define ASUS_HOTK_PREFIX "\\_SB.ATKD."
/*
@@ -169,6 +171,9 @@ ASUS_HANDLE(gps_on, ASUS_HOTK_PREFIX "SD
ASUS_HANDLE(gps_off, ASUS_HOTK_PREFIX "SDOF"); /* R2H */
ASUS_HANDLE(gps_status, ASUS_HOTK_PREFIX "GPST");
+/* hwmon */
+ASUS_HANDLE(hwmon_stat, ASUS_HOTK_PREFIX "TMPR");
+
/*
* This is the main structure, we can use it to store anything interesting
* about the hotk device
@@ -245,6 +250,8 @@ ASUS_LED(rled, "record");
ASUS_LED(pled, "phone");
ASUS_LED(gled, "gaming");
+typedef enum { SHOW_NAME, SHOW_LABEL, SHOW_INPUT, SHOW_FAN } SHOW;
+
/*
* This function evaluates an ACPI method, given an int as parameter, the
* method is searched within the scope of the handle, can be NULL. The output
@@ -709,6 +716,43 @@ static ssize_t store_gps(struct device *
return store_status(buf, count, NULL, GPS_ON);
}
+static int read_tmpr(void)
+{
+ ulong value = 0;
+ acpi_status rv = AE_OK;
+
+ if (hwmon_stat_handle) {
+ rv = acpi_evaluate_integer(hwmon_stat_handle, NULL,
+ NULL, &value);
+ if (ACPI_FAILURE(rv))
+ printk(ASUS_WARNING "Error reading temperature\n");
+ }
+
+ return value;
+}
+
+static ssize_t show_cpu_temp(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", ((read_tmpr() & 0xffff) - 2730) * 100);
+}
+
+static ssize_t show_fan_speed(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", (((read_tmpr() >> 16) & 0xff)-18) * 100);
+}
+
+static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+ if (attr->index == SHOW_LABEL)
+ return sprintf(buf, "CPU-Temp\n");
+
+ return sprintf(buf, "%s\n", ASUS_HOTK_FILE);
+}
+
static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
{
/* TODO Find a better way to handle events count. */
@@ -750,6 +794,11 @@ static void asus_hotk_notify(acpi_handle
dev_attr_##_name.store = _store; \
} while(0)
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_cpu_temp, NULL, SHOW_INPUT);
+static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_speed, NULL, SHOW_FAN);
+static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
+
static ASUS_CREATE_DEVICE_ATTR(infos);
static ASUS_CREATE_DEVICE_ATTR(wlan);
static ASUS_CREATE_DEVICE_ATTR(bluetooth);
@@ -768,6 +817,10 @@ static struct attribute *asuspf_attribut
&dev_attr_ls_switch.attr,
&dev_attr_ls_level.attr,
&dev_attr_gps.attr,
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_temp1_label.dev_attr.attr,
+ &sensor_dev_attr_fan1_input.dev_attr.attr,
+ &sensor_dev_attr_name.dev_attr.attr,
NULL
};
@@ -783,6 +836,7 @@ static struct platform_driver asuspf_dri
};
static struct platform_device *asuspf_device;
+static struct class_device *asushw_device;
static void asus_hotk_add_fs(void)
{
@@ -944,6 +998,8 @@ static int asus_hotk_get_info(void)
ASUS_HANDLE_INIT(gps_off);
ASUS_HANDLE_INIT(gps_status);
+ ASUS_HANDLE_INIT(hwmon_stat);
+
kfree(model);
return AE_OK;
@@ -1086,6 +1142,9 @@ static void asus_led_exit(void)
static void __exit asus_laptop_exit(void)
{
+ if (asushw_device)
+ hwmon_device_unregister(asushw_device);
+
asus_backlight_exit();
asus_led_exit();
@@ -1201,7 +1260,7 @@ static int __init asus_laptop_init(void)
if (result)
goto fail_platform_driver;
- asuspf_device = platform_device_alloc(ASUS_HOTK_FILE, -1);
+ asuspf_device = platform_device_alloc(ASUS_HOTK_FILE, 0);
if (!asuspf_device) {
result = -ENOMEM;
goto fail_platform_device1;
@@ -1216,6 +1275,15 @@ static int __init asus_laptop_init(void)
if (result)
goto fail_sysfs;
+
+ printk(ASUS_INFO "register hwmon interface\n");
+ asushw_device = hwmon_device_register(&asuspf_device->dev);
+ if (IS_ERR(asushw_device)) {
+ result = PTR_ERR(asushw_device);
+ asushw_device = NULL;
+ printk(ASUS_ERR "Unable to register hwmon device\n");
+ }
+
return 0;
fail_sysfs:
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Acpi4asus-user mailing list
Acpi4asus-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/acpi4asus-user