Skip to content

Commit

Permalink
add fan_speed and fan_mode to kernel module
Browse files Browse the repository at this point in the history
  • Loading branch information
vvvrrooomm committed Dec 17, 2020
1 parent ff7c268 commit b4c19cb
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 1 deletion.
38 changes: 38 additions & 0 deletions daemon/openrazer_daemon/dbus_services/dbus_methods/all.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,41 @@ def get_matrix_dims(self):
self.logger.debug("DBus call has_matrix")

return list(self.MATRIX_DIMS)


@endpoint('razer.device.misc', 'setFanSpeed', in_sig='yy')
def set_fan_speed(self, fan_id, fan_speed):
"""
set fan speed
:param fan_id: might change fans separately if more than one available (ususally 0x00)
:param fan_speed: speed in RPM/100
Values appear to be RPM/100, observed were 0x2b - 0x36, i.e. 4300RPM - 5400RPM
"""

self.logger.debug("DBus call set_fan_speed")

driver_path = self.get_driver_path('fan_speed')

payload = bytes([fan_id, fan_speed])

with open(driver_path, 'wb') as driver_file:
driver_file.write(payload)


@endpoint('razer.device.misc', 'setFanMode', in_sig='yy')
def set_fan_mode(self, fan_id, fan_mode):
"""
set fan mode
:param fan_id: might change fans separately if more than one available (ususally 0x00)
:param fan_mode: 0x00: automatic 0x01: manual
"""

self.logger.debug("DBus call set_fan_mode")

driver_path = self.get_driver_path('fan_mode')

payload = bytes([fan_id, fan_mode])

with open(driver_path, 'wb') as driver_file:
driver_file.write(payload)
2 changes: 1 addition & 1 deletion daemon/openrazer_daemon/hardware/keyboards.py
Original file line number Diff line number Diff line change
Expand Up @@ -1122,7 +1122,7 @@ class RazerBladeEarly2020Base(_RippleKeyboard):
USB_PID = 0x0255
HAS_MATRIX = True
MATRIX_DIMS = [1, 16]
METHODS = ['get_device_type_keyboard', 'set_wave_effect', 'set_static_effect', 'set_spectrum_effect',
METHODS = ['get_device_type_keyboard', 'set_fan_speed', 'set_fan_mode', 'set_wave_effect', 'set_static_effect', 'set_spectrum_effect',
'set_reactive_effect', 'set_none_effect', 'set_breath_random_effect', 'set_breath_single_effect',
'set_breath_dual_effect', 'set_custom_effect', 'set_key_row',
'set_starlight_random_effect', 'set_starlight_single_effect', 'set_starlight_dual_effect',
Expand Down
38 changes: 38 additions & 0 deletions driver/razerchromacommon.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,45 @@ struct razer_report razer_chroma_standard_get_led_rgb(unsigned char variable_sto
return report;
}

/*
* sets fan speed
*
*/
struct razer_report razer_chroma_set_fan_speed(unsigned char fan_id, unsigned char fan_speed)
{
struct razer_report report = get_razer_report(0x0d, 0x01, 0x03);
report.arguments[0] = 0x00; //frame_id: fixed value
report.arguments[1] = fan_id; //maybe fans can be set separately by id?
report.arguments[2] = fan_speed;

return report;
}


struct razer_report razer_chroma_get_fan_speeed(unsigned char fan_id)
{
struct razer_report report = get_razer_report(0x0d, 0x84, 0x03);
report.transaction_id.id = 0x3F;

report.arguments[0] = 0x00;
report.arguments[1] = fan_id;

return report;
}

/*
* sets fan mode - manual or automatic
*/
struct razer_report razer_chroma_set_fan_mode(unsigned char fan_id, unsigned char fan_mode)
{
struct razer_report report = get_razer_report(0x0d, 0x02, 0x04);
report.arguments[0] = 0x00; //frame_id: fixed value
report.arguments[1] = fan_id; //maybe fans can be set separately by id?
report.arguments[2] = 0x00; // unknown observed: 0x00
report.arguments[3] = fan_mode;

return report;
}



Expand Down
7 changes: 7 additions & 0 deletions driver/razerchromacommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ struct razer_report razer_chroma_standard_get_led_brightness(unsigned char varia

/*
* Standard Matrix Effects Functions
* class 0x03
*/
struct razer_report razer_chroma_standard_matrix_effect_none(unsigned char variable_storage, unsigned char led_id);
struct razer_report razer_chroma_standard_matrix_effect_wave(unsigned char variable_storage, unsigned char led_id, unsigned char wave_direction);
Expand Down Expand Up @@ -87,6 +88,12 @@ struct razer_report razer_chroma_mouse_extended_matrix_effect_breathing_random(u
struct razer_report razer_chroma_mouse_extended_matrix_effect_breathing_single(unsigned char variable_storage, unsigned char led_id, struct razer_rgb *rgb1);
struct razer_report razer_chroma_mouse_extended_matrix_effect_breathing_dual(unsigned char variable_storage, unsigned char led_id, struct razer_rgb *rgb1, struct razer_rgb *rgb2);

/*
* Fan control
* class 0x0d as well
*/
struct razer_report razer_chroma_set_fan_speed(unsigned char fan_id, unsigned char fan_speed);
struct razer_report razer_chroma_set_fan_mode(unsigned char fan_id, unsigned char fan_mode);

/*
* Misc Functions
Expand Down
57 changes: 57 additions & 0 deletions driver/razerkbd_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,56 @@ static ssize_t razer_attr_write_mode_macro_effect(struct device *dev, struct dev
return count;
}


/**
* write device file "fan_speed"
*
* fan_id: might allow to change fans separately if more than one exists
* fan_speed: speed in RPM/100
* Values appear to be RPM/100, observed were 0x2b - 0x36, i.e. 4300RPM - 5400RPM
*/
static ssize_t razer_attr_write_fan_speed(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct usb_interface *intf = to_usb_interface(dev->parent);
struct usb_device *usb_dev = interface_to_usbdev(intf);
struct razer_report report;
struct razer_report response;

switch(usb_dev->descriptor.idProduct) {
case USB_DEVICE_ID_RAZER_BLADE_EARLY_2020_BASE:
default:
if (count < 2) printk(KERN_WARNING "razerkbd: fan speed expects 2 bytes: fan_id, fan_speed");
report = razer_chroma_set_fan_speed(buf[0], buf[1]);
break;
}
response = razer_send_payload(usb_dev, &report);
return count;
}


/**
* Write device file "fan_mode"
*
* Returns a string
*/
static ssize_t razer_attr_write_fan_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct usb_interface *intf = to_usb_interface(dev->parent);
struct usb_device *usb_dev = interface_to_usbdev(intf);
struct razer_report report = razer_chroma_standard_set_led_effect(VARSTORE, BACKLIGHT_LED, 0x02);
struct razer_report response;

switch(usb_dev->descriptor.idProduct) {
case USB_DEVICE_ID_RAZER_BLADE_EARLY_2020_BASE:
default:
if (count < 2) printk(KERN_WARNING "razerkbd: fan speed expects 2 bytes: fan_id, fan_mode");
report = razer_chroma_set_fan_mode(buf[0], buf[1]);
break;
}
response = razer_send_payload(usb_dev, &report);
return count;
}

/**
* Read device file "macro_mode_effect"
*
Expand Down Expand Up @@ -2006,6 +2056,9 @@ static DEVICE_ATTR(key_super, 0660, razer_attr_read_key_super,
static DEVICE_ATTR(key_alt_tab, 0660, razer_attr_read_key_alt_tab, razer_attr_write_key_alt_tab);
static DEVICE_ATTR(key_alt_f4, 0660, razer_attr_read_key_alt_f4, razer_attr_write_key_alt_f4);

static DEVICE_ATTR(fan_speed, 0220, NULL, razer_attr_write_fan_speed);
static DEVICE_ATTR(fan_mode, 0220, NULL, razer_attr_write_fan_mode);




Expand Down Expand Up @@ -2471,6 +2524,8 @@ static int razer_kbd_probe(struct hid_device *hdev, const struct hid_device_id *
CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_effect_custom); // Custom effect
CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_matrix_custom_frame); // Set LED matrix
CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_logo_led_state); // Enable/Disable the logo
CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_fan_speed); // set fan speed
CREATE_DEVICE_FILE(&hdev->dev, &dev_attr_fan_mode); // set fan mode
break;

case USB_DEVICE_ID_RAZER_BLACKWIDOW_CHROMA:
Expand Down Expand Up @@ -2789,6 +2844,8 @@ static void razer_kbd_disconnect(struct hid_device *hdev)
device_remove_file(&hdev->dev, &dev_attr_matrix_effect_custom); // Custom effect
device_remove_file(&hdev->dev, &dev_attr_matrix_custom_frame); // Set LED matrix
device_remove_file(&hdev->dev, &dev_attr_logo_led_state); // Enable/Disable the logo
device_remove_file(&hdev->dev, &dev_attr_fan_speed); // set fan speed
device_remove_file(&hdev->dev, &dev_attr_fan_mode); // set fan mode
break;

case USB_DEVICE_ID_RAZER_BLACKWIDOW_CHROMA:
Expand Down
47 changes: 47 additions & 0 deletions examples/fan_control.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import colorsys
import random

from openrazer.client import DeviceManager
from openrazer.client import constants as razer_constants

# Create a DeviceManager. This is used to get specific devices
device_manager = DeviceManager()


print("Found {} Razer devices".format(len(device_manager.devices)))
print()

# Disable daemon effect syncing.
# Without this, the daemon will try to set the lighting effect to every device.
device_manager.sync_effects = False

# List of effect I've chosen to make an example for
effects = [
'fan_mode',
'fan_speed'
]

mode_manual = 0x01
mode_automatic = 0x01
high_speed = 0x36
low_speed = 0x2b

# Iterate over each device and set a random effect that it supports.
for device in device_manager.devices:
# Check which effect this device supports.
device_effects = [effect for effect in effects if device.fx.has(effect)]
# print("{} supports {}".format(device.name, device_effects))

if len(device_effects) == 0:
print("Device {} doesn't support any of the effects".format(device.name))
continue
effect = random.choice(device_effects)
print("Setting {} to effect {}".format(device.name, effect))

# Ad an example for each effect
if effect == 'fan_mode':
device.fx.fan_mode(mode_automatic)

elif effect == 'fan_speed':
device.fx.fan_speed(high_speed)
device.fx.fan_mode(mode_manual)
2 changes: 2 additions & 0 deletions pylib/openrazer/_fake_driver/razerblade15baseearly2020.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ files = r,device_serial,XX0000000255
r,device_type,%(name)s
r,firmware_version,v1.0
r,kbd_layout,01
w,set_fan_speed
w_set_fan_mode
rw,matrix_brightness,0
w,matrix_effect_breath
w,matrix_effect_none
Expand Down
37 changes: 37 additions & 0 deletions pylib/openrazer/client/devices/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ def __init__(self, serial, vid_pid=None, daemon_dbus=None):
'macro_logic': self._has_feature('razer.device.macro'),
'keyboard_layout': self._has_feature('razer.device.misc', 'getKeyboardLayout'),

'fan_speed': self._has_feature('razer.device.misc', 'setFanSpeed'),
'fan_mode': self._has_feature('razer.device.misc', 'setFanMode'),

# Default device is a chroma so lighting capabilities
'lighting': self._has_feature('razer.device.lighting.chroma'),
'lighting_breath_single': self._has_feature('razer.device.lighting.chroma', 'setBreathSingle'),
Expand Down Expand Up @@ -364,6 +367,40 @@ def __str__(self):
def __repr__(self):
return '<{0} {1}>'.format(self.__class__.__name__, self._serial)

def set_fan_speed(self, fan_id: int, fan_speed: int) -> bool:
"""
Fan Speed
:param fan_id: usually 0x00
:param fan_speed: values observed: 0x2b - 0x36
:return: True if success, False otherwise
:rtype: bool
:raises ValueError: If parameters are invalid
"""

self._dbus_interfaces['device'].setFanSpeed(fan_id, fan_speed)

return True

def set_fan_mode(self, fan_id: int, fan_mode: int) -> bool:
"""
Fan Mode
:param fan_id: usually 0x00
:param fan_speed: 0x00: automatic 0x01: manual
:return: True if success, False otherwise
:rtype: bool
:raises ValueError: If parameters are invalid
"""

self._dbus_interfaces['device'].setFanMode(fan_id, fan_mode)

return True


class BaseDeviceFactory(object):
@staticmethod
Expand Down

0 comments on commit b4c19cb

Please sign in to comment.