-
-
Save daringer/721e2cea17b570512097 to your computer and use it in GitHub Desktop.
OLD/DEPRECATED/OBSOLETE/DONOTUSE: ASUS Fan control linux kernel module - NOW HERE: https://github.com/daringer/asus-fan
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* ASUS Zenbook Fan control module, verified with: | |
* - UX32VD Zenbook | |
* - .... | |
* | |
* Just 'make' and copy the fan.ko file to /lib/modules/`uname -r`/... | |
* If the modules loads succesfully it will bring up a "thermal_cooling_device" | |
* like /sys/devices/virtual/thermal/cooling_deviceX/ mostly providing | |
* cur_state / max_state | |
* | |
* PLEASE USE WITH CAUTION, you can easily overheat your machine with a wrong | |
* manually set fan speed... | |
* | |
**/ | |
#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_AUTHOR("Markus Meissner <[email protected]>"); | |
MODULE_DESCRIPTION("ASUS fan driver"); | |
MODULE_LICENSE("GPL"); | |
static struct thermal_cooling_device *cdev; | |
static int last_state; | |
static bool is_manual; | |
static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state); | |
static int fan_set_auto(struct thermal_cooling_device *cdev); | |
static int fan_set(struct thermal_cooling_device *cdev, int fan, int speed); | |
static int fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state); | |
static void __exit fan_exit(void); | |
static int __init fan_init(void); | |
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; | |
// fan does not report during manual speed setting - so fake it! | |
if (is_manual) { | |
*state = last_state; | |
return 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) | |
{ | |
last_state = state; | |
// setting fan to automatic, if cur_state is set to (0x0100) 256 | |
if(state == 256) { | |
is_manual = false; | |
return fan_set_auto(cdev); | |
} else { | |
is_manual = true; | |
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); | |
last_state = -1; | |
is_manual = false; | |
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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
startpath="/sys/devices/virtual/thermal/" | |
path=$(grep -r Fan ${startpath}/cooling_device*/type 2> /dev/null | \ | |
cut -d ":" -f 1 | xargs dirname) | |
if [[ "$1" = "" ]]; then | |
echo "Usage: $0 <action>" | |
exit; | |
fi | |
if [[ "$1" = "max" || "$1" = "full" || "$1" = "get_max" ]]; then | |
cat ${path}/max_state | |
elif [[ "$1" = "cur" || "$1" = "get" || "$1" = "current" ]]; then | |
cat ${path}/cur_state | |
elif [[ "$1" = "set" && "$2" != "" ]]; then | |
echo $2 > ${path}/cur_state | |
echo "Set to 256 to reactivate automatic regulation!" | |
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
obj-m := asus_fan.o | |
KDIR := /lib/modules/$(shell uname -r)/build | |
PWD := $(shell pwd) | |
all: | |
$(MAKE) -C $(KDIR) M=$(PWD) modules | |
install: | |
# just copy the .ko file anywhere below: | |
# /lib/modules/$(uname -r)/ | |
# | |
# finally add it to some on-boot-load-mechanism | |
# the module will _not_ automatically load. |
how to use all this ?!
made 3 files in a directory and ran make install and it gave me error
makefile:6: *** missing separator. Stop.
i guess i will stop using gnu linux os since hardware manufacturers use gnu linux for themselves to boot a cd or in their hardware tools but dont want to support it.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
wohooo, I've made something useful :D the recent version adds support for the second fan for the dedicated gfx if there is one ... As there are new Zenbooks announced, which seem to use a similar/identical interface, I'll try to (somehow) push it towards mainstream - but haven't done this before, lets see how far I get before I'll start to cry the first time ;DDD
edit: and stop writing here, fill the issues in https://github.com/daringer/asus-fan with stuff you need ...