-
-
Save felipec/6169047 to your computer and use it in GitHub Desktop.
/* | |
* | |
* obj-m := fan.o | |
* KDIR := /lib/modules/$(shell uname -r)/build | |
* PWD := $(shell pwd) | |
* | |
* all: | |
* $(MAKE) -C $(KDIR) M=$(PWD) modules | |
* | |
* clean: | |
* $(MAKE) -C $(KDIR) M=$(PWD) clean | |
*/ | |
#include <linux/module.h> | |
#include <linux/kernel.h> | |
#include <linux/init.h> | |
#include <linux/acpi.h> | |
#include <linux/thermal.h> | |
#include <linux/dmi.h> | |
MODULE_AUTHOR("Felipe Contreras <[email protected]>"); | |
MODULE_DESCRIPTION("ASUS fan driver"); | |
MODULE_LICENSE("GPL"); | |
static struct thermal_cooling_device *cdev; | |
static int fan_get_max_state(struct thermal_cooling_device *cdev, | |
unsigned long *state) | |
{ | |
*state = 0xff; | |
return 0; | |
} | |
static int fan_get_cur_state(struct thermal_cooling_device *cdev, | |
unsigned long *state) | |
{ | |
struct acpi_object_list params; | |
union acpi_object in_objs[1]; | |
unsigned long long value; | |
acpi_status r; | |
params.count = ARRAY_SIZE(in_objs); | |
params.pointer = in_objs; | |
in_objs[0].type = ACPI_TYPE_INTEGER; | |
in_objs[0].integer.value = 0; | |
r = acpi_evaluate_integer(NULL, "\\_TZ.RFAN", ¶ms, &value); | |
if (r != AE_OK) | |
return r; | |
*state = value; | |
return 0; | |
} | |
static int fan_set(struct thermal_cooling_device *cdev, int fan, int speed) | |
{ | |
struct acpi_object_list params; | |
union acpi_object in_objs[2]; | |
unsigned long long value; | |
params.count = ARRAY_SIZE(in_objs); | |
params.pointer = in_objs; | |
in_objs[0].type = ACPI_TYPE_INTEGER; | |
in_objs[0].integer.value = fan; | |
in_objs[1].type = ACPI_TYPE_INTEGER; | |
in_objs[1].integer.value = speed; | |
return acpi_evaluate_integer(NULL, "\\_SB.PCI0.LPCB.EC0.SFNV", ¶ms, &value); | |
} | |
static int fan_set_cur_state(struct thermal_cooling_device *cdev, | |
unsigned long state) | |
{ | |
return fan_set(cdev, 1, state); | |
} | |
static int fan_set_auto(struct thermal_cooling_device *cdev) | |
{ | |
return fan_set(cdev, 0, 0); | |
} | |
static const struct thermal_cooling_device_ops fan_cooling_ops = { | |
.get_max_state = fan_get_max_state, | |
.get_cur_state = fan_get_cur_state, | |
.set_cur_state = fan_set_cur_state, | |
}; | |
static int __init fan_init(void) | |
{ | |
if (strcmp(dmi_get_system_info(DMI_SYS_VENDOR), "ASUSTeK COMPUTER INC.")) | |
return -ENODEV; | |
cdev = thermal_cooling_device_register("Fan", NULL, &fan_cooling_ops); | |
if (IS_ERR(cdev)) | |
return PTR_ERR(cdev); | |
fan_set_auto(cdev); | |
return 0; | |
} | |
static void __exit fan_exit(void) | |
{ | |
fan_set_auto(cdev); | |
thermal_cooling_device_unregister(cdev); | |
} | |
module_init(fan_init); | |
module_exit(fan_exit); |
I do have a "asus" part in sensors
when it is modprobed. However, cpu temperature is pretty much all I got. So I still don't have any fan informations...
If you don't have any informations, maybe you do not have acpi stuff installed...
@asuxer: thanks for the lkml link, I hope it will keep going on...
OK I give up...
I recompiled the original Ubuntu kernel, but patched it with the diff from here
https://lkml.org/lkml/2013/10/8/800
(http://www.gossamer-threads.com/lists/linux/kernel/1796054)
Reboot, then I re-run sensors-detect, then sudo pwmconfig (from package fancontrol) but still I get
/usr/sbin/pwmconfig: There are no fan-capable sensor modules installed
felipec, please tell us what you did. You say it works perfectly for you?
@asuxer this module don't create /sys/class/hwmon
devices. Control your fan with:
$ echo 200 | sudo tee /sys/class/thermal/cooling_deviceN/cur_state
- added full Makefile
- added "hack" to set fan back to automatic without unloading the module
-> forked here: https://gist.github.com/daringer/721e2cea17b570512097
Hi, I compiled and inserted the module too, but I'm stuck there, as the fan isn't seen by 'sensors' program, and there seems to be no way to control it.
What I'm I missing? Do I need to recompile the kernel with the modified asus-laptop.c?
By the way, I'm running Arch Linux on 3.10.9-1 stock kernel.
Thank you.