Samsung Galaxy Book series extras Linux platform driver.
Current status: ⚠️ WIP but nearing readiness for mainline ⚠️ (use at your own risk!)
The intent is to somewhat replicate in Linux what Samsung has done in Windows with what I think the following components are doing:
SCAI
ACPI device in order to control a lot of these settings.SamsungSystemSupportEngine.exe
which seems to handle quite a lot of things on the userspace/application side, including:
This is a new and (currently) completely out-of-tree kernel platform driver intended to mimic what the Samsung System Event Controller Windows system device driver seems to be doing (namely, communicate with the SCAI
ACPI device in order to control these extra features). Once more features have been added and it has been tested then my intention is to try and submit the driver to be added to the kernel.
The following features are currently implemented:
fan_speed_rpm
sysfs attribute plus a new hwmon deviceThe following features might be possible to implement but require additional debugging and development:
SAM0427
The devices supported by this platform driver should be any device where sudo dmidecode --type 3
reports Manufacturer: SAMSUNG ELECTRONICS CO., LTD.
and Type: Notebook
, PLUS that the ACPI device SCAI
is present with ACPI Device IDs matching the list given in the driver (SAM0427
, SAM0428
, and SAM0429
at the time of this writing). This covers most of the currently available "Samsung Galaxy Book" series notebooks, but could include others as well.
Note that for the devices with the ACPI Device ID SAM0427
, there will currently not be support for:
If you have a device with SAM0427
and wish to help provide support to overcome the above limitations, please feel free to create an issue!
I have also seen that Windows uses the same driver for SAM0426
(used by devices like the Notebook 9 Pro 15" and/or similar), so my suspicion is that large parts of this driver probably also work for these devices. If you have one of these devices, and want to test this driver with it, please create an issue for help and to share your findings.
The platform driver supports the following module parameters:
kbd_backlight
: Enable Keyboard Backlight control (default on) (bool)battery_threshold
: Enable battery charge threshold control (default on) (bool)performance_mode
: Enable Performance Mode control (default on) (bool)fan_speed
: Enable fan speed (default on) (bool)i8042_filter
: Enable capturing keyboard hotkey events (default on) (bool)acpi_hotkeys
: Enable ACPI hotkey events (default on) (bool)wmi_hotkeys
: Enable WMI hotkey events (default on) (bool)debug
: Enable debug messages (default off) (bool)In general the intention of these parameters is to allow for enabling or disabling of various features provided by the driver, especially in cases where a particular feature does not appear to work with your device. The availability of the various "settings" flags (usb_charge
, start_on_lid_open
, etc) will always be enabled and cannot be disabled at this time.
Note: Please raise an issue if you find that you need to disable a certain feature in order to avoid a problem that it causes with your device!
Compile the module out-of-tree but against the currently loaded kernel's modules:
make -C /lib/modules/`uname -r`/build M=$PWD
Install this module into your currently loaded kernel's modules:
sudo make -C /lib/modules/`uname -r`/build M=$PWD modules_install
sudo depmod
Note: if you wish to enable
debug
by default then you can addsamsung_galaxybook.debug=true
to your boot parameters.
Load the module (including enabling debugging messages):
sudo modprobe samsung-galaxybook debug=true
Unload the module:
sudo rmmod samsung-galaxybook
Uninstall the module:
sudo rm /lib/modules/`uname -r`/updates/samsung-galaxybook.ko*
If you want to sign the driver to avoid the message samsung_galaxybook: module verification failed: signature and/or required key missing - tainting kernel
, then you will need to sign the module following whatever process is typical for your distribution. For Debian-based distrubutions (including Ubunutu), you can install the linux-source
package for your current kernel and used the included keys and scripts to sign the module as follows:
sudo rmmod samsung-galaxybook
/usr/src/`uname -r`/debian/scripts/sign-module sha512 /usr/src/`uname -r`/debian/certs/signing_key.pem /usr/src/`uname -r`/debian/certs/signing_key.x509 samsung-galaxybook.ko
sudo cp samsung-galaxybook.ko /lib/modules/`uname -r`/updates/samsung-galaxybook.ko
sudo modprobe samsung-galaxybook debug=true
The module parameters can be used to enable or disable most features. For example, the following would reload the module with only the core settings flags (usb_charge
, start_on_lid_open
, etc) and the kbd_backlight LED class, and all other features would be disabled:
sudo rmmod samsung-galaxybook
sudo modprobe samsung-galaxybook debug=false kbd_backlight=on battery_threshold=off performance_mode=off fan_speed=off i8042_filter=off acpi_hotkeys=off wmi_hotkeys=off
Note that these can also be added to the boot parameters (e.g. samsung_galaxybook.fan_speed=off
).
One general observation that I have made is that there are in fact quite a lot of bugs in Samsung's firmware for these devices, for example:
It would be great if we could actually get some help from Samsung regarding this!
Samsung have decided to use the main keyboard device to also send most of the hotkey events. If the driver wishes to capture and act on these hotkeys, then we will have to do something like using a i8402 filter to "catch" the key events.
I have also found that some of the hotkey events have conflicts so it is a bit of a tricky territory.
The keyboard backlight hotkey will cycle through all available backlight brightness levels in a round-robin manner, starting again at 0 when the maximum is reached (i.e. 0, 1, 2, 3, 0, 1, ...).
The action will be triggered on keyup of the hotkey as the event reported by keydown seems to be the same event for battery charging progress (and thus things get a little crazy when you start charging!).
The hotkey should also trigger the hardware changed event for the LED, which in GNOME (and likely others) automatically displays a nice OSD popup with the correct baclight level displayed.
The block recording hotkey will toggle the allow_recording
feature, which blocks access to the built-in camera and microphone.
The performance mode hotkey will also cycle through all available platform profiles in a round-robin manner (low-power, quiet, balanced, performance, low-power, quiet, ...).
There is currently no OSD popup but the event can be captured from the "Samsung Galaxy Book extra buttons" input device if desired.
There is a new input device created "Samsung Galaxy Book extra buttons" which will send input events for a few notifications from the ACPI device:
SAM0428
models only)SAM0428
models only)A new LED class called samsung-galaxybook::kbd_backlight
is created which can be controlled via sysfs
at /sys/class/leds/samsung-galaxybook::kbd_backlight/brightness
(values 0 to 3) or by many of the standard utilities such as brightnessctl
, light
, etc.
It also seems to be picked up automatically in GNOME 45.x in the panel, where you can click the arrow beside Keyboard
and adjust the slider.
Note that the setting "automatically turn off the keyboard backlight after X seconds" in Windows is actually controlled by Samsung's application service and not by the device driver itself; there is a similar feature in GNOME (and again, likely others) where it toggles to the minimum level after a certain idle period (e.g. from 3 to 1 when you are idle, and then back to 3 when you resume), but regardless this feature should probably be controlled in the userspace somehow and not by the kernel driver.
Also note that most of these devices have an ambient light sensor which also affects the keyboard backlight. This behavior is not possible to control in Windows and I have not yet found anything in the ACPI that seems to be able to disable this feature. What this means is that sometimes you might think that the keyboard backlight is just randomly turning off or has stopped working, but the reality is that it is turning off due to this ambient light sensor. One way to test when this happens (to be sure that it is in fact the ambient light sensor which has caused the keyboard backlight to turn off) is to just cover the sensor somehow (with your finger, for example), and see if the lights come back on.
This platform driver will add setting the battery charge control end threshold, but does not have access to set the start threshold. This feature is typically called "battery saver" by the various Samsung applications in Windows, but in Linux we will implement the standard attributes added to the battery device that are recognized by UPower.
If the user wishes to maintain interoperability with Windows, then they should set the value to 80 to represent "on", or 0 to represent "off", as these are the values recognized by the various Windows-based Samsung applications and services as "on" or "off". Otherwise, the device will accept any value between 0 (off) and 99 as a percentage that you wish the battery to stop charging at. If you try to set a value of 100, the driver will also accept this input, but just set the attribute value to 0 (i.e. 100% is interpreted as "turn battery saver off").
There is a new device attribute created at /sys/class/power_supply/BAT1/charge_control_end_threshold
which can be read from or written to.
# read current value (percentage the battery will stop charging)
cat /sys/class/power_supply/BAT1/charge_control_end_threshold
# turn on and set to 80%
echo 80 | sudo tee /sys/class/power_supply/BAT1/charge_control_end_threshold
# turn off charge control threshold so that charging will not be stopped before 100%
echo 0 | sudo tee /sys/class/power_supply/BAT1/charge_control_end_threshold
Note: I have noticed that if you are currently plugged while the battery is already sitting at the desired
charge_control_end_threshold
, then turn off this feature (i.e. you wish to charge fully to 100% so you set the value to 0), charging does not seem to start automatically. It may be necessary to disconnect and reconnect the charging cable in this case. The Windows driver seems to be doing some hocus-pocus with the ACPI battery device that I have not quite sorted out yet; I am assuming this is how they made it work more seamlessly in Windows?
There is also an input event sent to the standard keyboard and ACPI device which is generated when charge control is enabled and charging reaches the desired charge_control_end_threshold
; the event has been mapped to the BATTERY
event so that notifications can be displayed (see below in the keyboard remapping section for additional information on this).
To turn on or off the "Start on lid open" setting (the laptop will power on automatically when opening the lid), there is a new device attribute created at /sys/devices/platform/samsung-galaxybook/start_on_lid_open
which can be read from or written to. A value of 0 means "off" while a value of 1 means "on".
# read current value (0 for disabled, 1 for enabled)
cat /sys/devices/platform/samsung-galaxybook/start_on_lid_open
# turn on (supports values such as: 1, on, true, yes, etc)
echo true | sudo tee /sys/devices/platform/samsung-galaxybook/start_on_lid_open
# turn off (supports values such as: 0, off, false, no, etc)
echo 0 | sudo tee /sys/devices/platform/samsung-galaxybook/start_on_lid_open
To turn on or off the "USB Charge" mode (allows USB ports to provide power even when the laptop is turned off), there is a new device attribute created at /sys/devices/platform/samsung-galaxybook/usb_charge
which can be read from or written to. A value of 0 means "off" while a value of 1 means "on".
# read current value (0 for disabled, 1 for enabled)
cat /sys/devices/platform/samsung-galaxybook/usb_charge
# turn on (supports values such as: 1, on, true, yes, etc)
echo true | sudo tee /sys/devices/platform/samsung-galaxybook/usb_charge
# turn off (supports values such as: 0, off, false, no, etc)
echo 0 | sudo tee /sys/devices/platform/samsung-galaxybook/usb_charge
My own observations on how this feature appears to work (which has nothing to do with this driver itself, actually):
To turn on or off the "Allow recording" setting (allows or blocks usage of the built-in camera and microphone), there is a new device attribute created at /sys/devices/platform/samsung-galaxybook/allow_recording
which can be read from or written to. A value of 0 means "off" while a value of 1 means "on".
The Samsung user manual calls this setting "Blocking Recording mode", but as the value needed is 1 for "not blocked" and 0 for "blocked" (i.e. the value of 1 vs 0 feels "backwards" compared to the name), it felt like something of a misnomer to call it that for this driver. It seems to make more sense that 1 means "allowed" and 0 means "not allowed"; this way, it is hopefully more obvious to the user of this driver what will actually happen when this value is changed.
# read current value (0 for disabled, 1 for enabled)
cat /sys/devices/platform/samsung-galaxybook/allow_recording
# turn on (supports values such as: 1, on, true, yes, etc)
echo true | sudo tee /sys/devices/platform/samsung-galaxybook/allow_recording
# turn off (supports values such as: 0, off, false, no, etc)
echo 0 | sudo tee /sys/devices/platform/samsung-galaxybook/allow_recording
Different devices have different number of fans, and different methods in order to be able to successfully read their status. Samsung does seem to have implemented the ACPI standard fan device method _FST
for most of the various implementations, but not the other optional methods in the ACPI specification which would cause the kernel to automatically add the fan_speed_rpm
attribute. On top of this, it seems that there are some bugs in the firmware that often throw an exception when you try to execute this ACPI method. This behavior is also seen in Windows (that an ACPI exception is thrown when the fan speed is attempted to be checked), and I have not been able to see fan speeds using various hardware monitoring applications while using Windows with this device.
This platform driver attempts to resolve all PNP fans that are available in the ACPI and add support for reading their speed using the following decision logic:
_FST
exist and appears to be working (returns a speed value greater than 0)? If yes, add an attribute fan_speed_rpm
to it and as a fan input channel to the hwmon device.FANS
(fan speed level) exist on the embedded controller, and the table FANT
(fan speed level table) exist on the fan? If so, add the fan_speed_rpm
to this fan device, plus as a fan input channel to the hwmon device, and build the list of custom fan speeds based on the below logic (derived from reading the DSDT and trying to interpret the intention of how the original _FST
seems to want to work).The fan speed can be monitored using hwmon sensors or by reading the fan_speed_rpm
sysfs attribute.
# read current fan speed rpm from sysfs attribute
cat /sys/bus/acpi/devices/PNP0C0B\:00/fan_speed_rpm
# read current fan speed rpm from hwmon device
sensors
For devices where the _FST
method does not work correctly, the below logic is used in order to derive possible speeds for each available level reported by the FANS
field.
FANT
("fan table"?) which seems to be some kind of list of possible RPM speeds that the fan can operate at for each different "level" (0 through 5).FANS
("fan speed"?) which seems to give the current "level" that the fan is operating at.I have assumed that the values from FANT
are integers which represent the actual RPM values (they seem reasonble, anyway), but can't be one-hundred percent certain that this assumption is correct. It would be interesting to get confirmation from Samsung or if someone has a way to measure the actual speed of the fan.
The fan can either be completely off (0) or one of the levels represented by the speeds in FANT
. This driver reads the values in from FANT
instead of hard-coding the levels with the assumption that it could be different values and a different number of levels for different devices. For reference, the values I see with my Galaxy Book2 Pro are:
On top of this, in Samsung's _FST
method it seems to be adding 0x0a
(10) to each value before trying to report them, and that level 3 and 4 should have the same value, while level 5 should be the 4th value from FANT
. However, real-life observation suggests that level 3 and 4 are in fact different, and that level 5 seems to be significantly louder than level 4. Due to this, this driver will just "guess" that levels 3 and 4 are actually as is listed in FANT
, and that the last level is maybe 1000 RPM faster than level 4 (unless anyone can find something better than this!).
There is a test SSDT available in the file gb_test_fans_ssdt.dsl which includes a set of "faked" PNP ACPI fan devices that can be used to test how the driver works with different scenarios. This can be built and loaded dynamically but you will also need to remove and reload the platform driver module in order to test how they will be handled by it.
# create fake device table
sudo modprobe acpi_configfs
sudo mkdir /sys/kernel/config/acpi/table/gb_test_fans_ssdt
# build and load the aml
iasl gb_test_fans_ssdt.dsl
cat gb_test_fans_ssdt.aml | sudo tee /sys/kernel/config/acpi/table/gb_test_fans_ssdt/aml
# remove and reload the module (via insmod or modprobe)
sudo rmmod samsung-galaxybook
sudo insmod samsung-galaxybook.ko debug=true
Note: You will need to restart in order to remove these fake devices.
To modify the "performance mode", the driver implements the platform_profile
interface. Mapping of Samsung's "Performance modes" to their respective platform profile is done dynamically based on a mapping in the driver code which reads in what modes are reported as supported by the ACPI. Preference is given to try and map low-power
, balanced
, and performance
profiles, as these seem to be the most common profiles utilized (and sometimes even required) by various userspace tools.
The result of the mapping will be printed in the Kernel log when the module is loading. Supported profiles can then be retrieved from /sys/firmware/acpi/platform_profile_choices
, while /sys/firmware/acpi/platform_profile
can be used to read or write the desired profile.
Examples:
# Get supported platform profiles
cat /sys/firmware/acpi/platform_profile_choices
# set platform profile to low-power
echo low-power | sudo tee /sys/firmware/acpi/platform_profile
# get current platform profile
cat /sys/firmware/acpi/platform_profile
Note: To match the logic in the Windows driver, as well as avoid causing issues with other features, the driver currently will always set the performance mode to "Optimized" every time during its initialization (e.g. upon startup).
It should be possible to set your own desired startup performance mode or to save and restore the mode across reboots, you can eiter use a startup script or install TLP, power-profiles-daemon, or similar.
This was a bit hard to test, but I tried to see if these different modes actually made a measurable change by setting each different mode and then running a quick stress test using the following:
sudo stress-ng --cpu 0 --cpu-load 100 --metrics-brief --perf -t 20
Note that it does seem to take at least a few seconds before the setting really seems to kick in.
In the end what I found was that I could definitely tell a difference in the result when using the "silent" (0) mode, because the resulting number of completed operations in the stress test was significantly lower when using "silent" mode (almost half).
Subjectively, I do feel like I experienced that the fan volume was quite a bit lower in the "quiet" mode as compared to the other two, but I did not really notice any major difference in the number of completed operations from the stress test. Optimized and High Performance seemed almost the same to me. I did also notice that there might be some throttling happening when the cores reach near 100C, so maybe that is part of the problem why I could not tell a difference (not sure what is safe to adjust). This could also just be a flawed test mechanism, as well!
The provided file 61-keyboard-samsung-galaxybook.hwdb is a copy of the relevant section for these devices from the latest 60-keyboard.hwdb which can be used with older versions of systemd. See systemd/issues/34646 and systemd/pull/34648 for additional information.
Note: The "Performance mode" key (Fn+F11) comes as an ACPI notification and is handled by the
samsung-galaxybook
platform driver.
You can install this mapping file as follows:
sudo cp 61-keyboard-samsung-galaxybook.hwdb /etc/udev/hwdb.d/
sudo systemd-hwdb update
sudo udevadm trigger