Blame the manufacturer.This is a very common issue that few people realise.
The Advanced Configuration and Power Interface (ACPI) contains the Differentiated Services Description Table (DSDT). The DSDT is byte-code that the active operating system executes within its ACPI pseudo-virtual machine interpreter.
This code provides executable Methods (functions) that perform configuration of hardware components; especially related to power control, enabling/disabling devices (think WiFi radio kill-switch), acting on special platform hot-keys (such as Fn+brightness-{up/down} and much more).
It also contains initial feature configuration methods which enable features based on the operating system identity (OSI). In most DSDTs I've analysed over the last 10 years (and I made a special study of Sony models) the OSI code will only enable the full range of features when the host operating system is Windows.
Generally, when the Windows operating system calls the the OSI methods it passes a text string of the form "Windows XXXX" where XXXX is a year number representing the Windows version. Based on XXXX the OSI method then sets the value of a 'feature' variable, with newer versions of Windows enabling more features.
The default value of the 'feature' variable is usually the lowest possible value. This value is adopted when the host operating system is Linux since the OSI method doesn't recognised the OSI "Linux" string.
To work around this problem Linux kernel provides a command-line configuration parameter that enables it to report itself as another operating system. Using this to 'pretend' to be the latest Windows version recognised by the ACPI DSDT will almost always enable all features optimally.
The kernel parameter is "acpi_osi".
I've used this very recently on a new Asus T300 CHI that failed to enabled power to the USB-connected Synaptics touchscreen digitizer if the the device wasbooted whilst charging from mains.
I also fixed an Ubuntu user's problem last night on a Dell Inspiron where the touchpad would be jumpy and the battery drained very quickly.
In both cases there are 2 steps:
1. Identify the OSI strings the ACPI DSDT supports
2. Add what seems to be the latest Windows version string to the Linux kernel command-line
To find the OSI support strings the easy way (although this may not identify all strings) just extract the strings from the binary table. You could use 'iasl' to decompile the DSDT to source-doe but usually it is not necessary:
$ sudo strings /sys/firmware/acpit/tables/DSDT | grep -C 2 -i windows
The strings of interest will usually begin with "Microsoft" or "Windows". On the Asus T300 CHI they are:
Windows 2009
Windows 2012
Windows 2013
The latest is "Windows 2013".
On an older Dell XPS M5130 they are:
Microsoft Windows
Microsoft Windows NT
Microsoft WindowsME: Millennium Edition
Windows 2001
Windows 2006
The latest for the M1530 is "Windows 2006"
Edit the boot-loader's configuration to add the kernel command-line option to any existing settings. For GRUB2 that'll be editing /etc/default/grub:
GRUB_CMDLINE_LINUX="acpi_osi=! acpi_osi=\"Windows 2013\" "
Notice that we need to escape (\") the embedded double-quotation marks inside the variable definition in order for the quote marks to be written to the kernel command-line itself. After saving the file do:
$ sudo update-grub
which writes the changes to the GRUB2 boot-time configuration script: /boot/grub/grub.cfg
Each linux kernel boot entry (lines beginning "linux ...") will include the parameter similar to this:
linux vmlinuz .... acpi_osi=! acpi_osi="Windows 2013"
acpi_osi=! first deletes all recognised OSI strings.
acpi_osi="Windows 2013" sets the only recognised OSI
You can also test the option before adding it permanently by editing the boot-time boot menu entry. For GRUB2 that involves holding down the Shift key during the firmware POST until GRUB2 is loaded, which will cause GRUB2 to display its boot menu. From there highlight the entry to wish to modify, press 'E' to edit it, navigate down to the line beginning "inux ..." and add to the end of it:
acpi_osi=! acpi_osi="Windows 2013"
Obviously replace my OSI string with the one you've identified (or guessed) then press Ctrl+X or F10 (as noted in the on-screen hints) to immediately boot with this modified configuration.
You can check the current boot's active parameters with:
$ cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-4.4.0-21-lowlatency root=/dev/mapper/VG02-rootfs ro no_console_suspend initcall_debug debug acpi_osi=! "acpi_osi=Windows 2013" splash vt.handoff=7
If you have 'debug' level kernel logging enabled you might also see some ACPI OSI related messages in the dmesg kernel log:
Apr 24 04:30:07 T300CHI kernel: [ 0.106325] ACPI: Added _OSI(Windows 2013)