The A1 and A2 buttons on the panasonic toughpad FZ-G1-mk3 that I have don’t work in Linux. They are supposed to work and rumour has it that newer models have it working. I’m documenting the path that explains the path that I have had to take to get this working.
The purpose of this document is to ouline what I have learned about this process, with an intent that it may also help someone else along their journey. I plan to map my path to understanding how to get the buttons to work on this device and all the steps that I have taken along the way.
A number of people have written a driver for ‘panasonic-hbtn’ for other toughbook and toughpad devices ( see https://github.com/nagyrobi/panasonic-hbtn/network/members ) although none of them seem to have something working for the FZ-G1 (Mk1 -> mk3) family.
The closest work appears to be the FZ-M1 repository ( https://github.com/KaarelP2rtel/panasonic-hbtn ) this is the successor to the FZ-G1 family, but not the same.
Have libinput recognise this as a key:
$ libinput debug-events
-event2 KEYBOARD_KEY +4.976s KEY_VOLUMEDOWN (114) pressed event2 KEYBOARD_KEY +5.259s KEY_VOLUMEDOWN (114) released event2 KEYBOARD_KEY +7.129s KEY_VOLUMEUP (115) pressed -event2 KEYBOARD_KEY +7.374s KEY_VOLUMEUP (115) released
^ These are the volume up and down on the front of the device.
I’m expecting a new KEY_SOMETHING to happen.
As per ( https://www.kernel.org/doc/Documentation/acpi/debug.txt ), it mentions that you must be booting a kernel with CONFIG_ACPI_DEBUG=y enabled. The standard fedora kernel does is not compiled with this parameter.
# dnf install kernel-debug
Reboot the system, and choose the debug kernel.
[wmealing@toughpad ~]$ uname -a
Linux toughpad.localdomain 5.6.14-300.fc32.x86_64+debug #1 SMP Wed May 20 20:26:12 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
When you’re booting the right kernel, the acpi module should have this file created in sysfs.
/sys/module/acpi/parameters/debug_layer
The kernel acpi debug.txt above mentions that there are different layers that you can ‘enable’ debugging of, this is a ‘button’ so why not start there.
What is in that file:
[wmealing@toughpad parameters]$ cat debug_layer
Description Hex SET
ACPI_UTILITIES 0x00000001 [ ]
ACPI_HARDWARE 0x00000002 [ ]
ACPI_EVENTS 0x00000004 [ ]
ACPI_TABLES 0x00000008 [ ]
ACPI_NAMESPACE 0x00000010 [ ]
ACPI_PARSER 0x00000020 [ ]
ACPI_DISPATCHER 0x00000040 [ ]
ACPI_EXECUTER 0x00000080 [ ]
ACPI_RESOURCES 0x00000100 [ ]
ACPI_CA_DEBUGGER 0x00000200 [ ]
ACPI_OS_SERVICES 0x00000400 [ ]
ACPI_CA_DISASSEMBLER 0x00000800 [ ]
ACPI_COMPILER 0x00001000 [ ]
ACPI_TOOLS 0x00002000 [ ]
ACPI_BUS_COMPONENT 0x00010000 [ ]
ACPI_AC_COMPONENT 0x00020000 [ ]
ACPI_BATTERY_COMPONENT 0x00040000 [ ]
ACPI_BUTTON_COMPONENT 0x00080000 [ ]
ACPI_SBS_COMPONENT 0x00100000 [ ]
ACPI_FAN_COMPONENT 0x00200000 [ ]
ACPI_PCI_COMPONENT 0x00400000 [ ]
ACPI_POWER_COMPONENT 0x00800000 [ ]
ACPI_CONTAINER_COMPONENT 0x01000000 [ ]
ACPI_SYSTEM_COMPONENT 0x02000000 [ ]
ACPI_THERMAL_COMPONENT 0x04000000 [ ]
ACPI_MEMORY_DEVICE_COMPONENT 0x08000000 [ ]
ACPI_VIDEO_COMPONENT 0x10000000 [ ]
ACPI_PROCESSOR_COMPONENT 0x20000000 [ ]
ACPI_ALL_DRIVERS 0xFFFF0000 [ ]
--
debug_layer = 0x00000000 ( * = enabled)
Wow, thats kinda nice, a nice layout of the bitwise debugging. Lets enable the button ( 0x00080000 )
# echo 0x00080000 > /sys/module/acpi/parameters/debug_layer
# cat /sys/module/acpi/parameters/debug_layer |grep BUTTON
ACPI_BUTTON_COMPONENT 0x00080000 [*]
The * implies that it is enabled.
Lets watch the logs…
# dmesg -c &> /dev/null
# dmesg -w
And press the physical button. And no debugging events appear.. Ok, so I infer that perhaps this is the ‘kernel’ side of the handler code that we’d be looking at and there are no ‘kernel’ style events that are executing, now perhaps lets look at the ACPI.
The same debug.txt talks about “debug_level” file in the same module directory.
# cat /sys/module/acpi/parameters/debug_level
Description Hex SET
ACPI_LV_INIT 0x00000001 [ ]
ACPI_LV_DEBUG_OBJECT 0x00000002 [ ]
ACPI_LV_INFO 0x00000004 [*]
ACPI_LV_REPAIR 0x00000008 [*]
ACPI_LV_TRACE_POINT 0x00000010 [ ]
ACPI_LV_INIT_NAMES 0x00000020 [ ]
ACPI_LV_PARSE 0x00000040 [ ]
ACPI_LV_LOAD 0x00000080 [ ]
ACPI_LV_DISPATCH 0x00000100 [ ]
ACPI_LV_EXEC 0x00000200 [ ]
ACPI_LV_NAMES 0x00000400 [ ]
ACPI_LV_OPREGION 0x00000800 [ ]
ACPI_LV_BFIELD 0x00001000 [ ]
ACPI_LV_TABLES 0x00002000 [ ]
ACPI_LV_VALUES 0x00004000 [ ]
ACPI_LV_OBJECTS 0x00008000 [ ]
ACPI_LV_RESOURCES 0x00010000 [ ]
ACPI_LV_USER_REQUESTS 0x00020000 [ ]
ACPI_LV_PACKAGE 0x00040000 [ ]
ACPI_LV_ALLOCATIONS 0x00100000 [ ]
ACPI_LV_FUNCTIONS 0x00200000 [ ]
ACPI_LV_OPTIMIZATIONS 0x00400000 [ ]
ACPI_LV_MUTEX 0x01000000 [ ]
ACPI_LV_THREADS 0x02000000 [ ]
ACPI_LV_IO 0x04000000 [ ]
ACPI_LV_INTERRUPTS 0x08000000 [ ]
ACPI_LV_AML_DISASSEMBLE 0x10000000 [ ]
ACPI_LV_VERBOSE_INFO 0x20000000 [ ]
ACPI_LV_FULL_TABLES 0x40000000 [ ]
ACPI_LV_EVENTS 0x80000000 [ ]
--
debug_level = 0x0000000C (* = enabled)
By default there are a few, but from what I can see, there is nothing that happens with the current ‘button press’.
So, I choose some values from the internet:
echo 0x8400082 > /sys/module/acpi/parameters/debug_layer
echo 0x31000200 > /sys/module/acpi/parameters/debug_level
Now when pressed the system logs contain out a LOT of data. This at least confirms my suspicion that this is an ACPI related device. For the bulk of it , see here https://gist.github.com/wmealing/c050d23fd252667a2c420e2172bcefca . I figured that a lot of that may be duplicated as it executes for ‘up’ and ‘down’ of the keypress.
This is an ‘opcode’ and execution dump of the ACPI tables. I can’t make much sense of this at the moment, however I think these might be important.
$ dmesg | grep Notify |
[ 3161.313553] exdump-0603 ex_dump_operand : 0000000077ead245 Namespace Node: 0 HKEY Device 0000000077ead245 001 Notify Object: 0000000037c289c4
[ 3182.328379] exdump-0603 ex_dump_operand : 0000000077ead245 Namespace Node: 0 HKEY Device 0000000077ead245 001 Notify Object: 0000000037c289c4
[ 3205.726665] exdump-0603 ex_dump_operand : 0000000077ead245 Namespace Node: 0 HKEY Device 0000000077ead245 001 Notify Object: 0000000037c289c4
So, if i’m reading the spec ( https://www.intel.com/content/dam/www/public/us/en/documents/articles/acpi-config-power-interface-spec.pdf ) correctly, page 501. It says that “Notify” is notifying the OS that the event has happened.
My initial theory is that the OS is ignoring it. How can I find out if that is the case ?
There is a bunch of code within the drivers/acpi directory which includes the apci interpreter, this is likely where the dispatch takes place.. I assume that ‘events’ come in here, somehow and are matched to the handler.
Grab the dstd from the system.
$ cat /sys/firmware/acpi/tables/DSDT » /home/wmealing/DSTD
Maybe.. I see “HKEY” being mentioned in the in the debugging code above, this might be related
Decompile the code with the command.
$ iasl -d DSTD
In an attempt to figure out what the hell this is I came across:
Scope (_SB) // system bus ?
{
Device (HKEY) // hardware key
{
Name (_HID, EisaId ("MAT0019")) // _HID: Hardware ID
// <-- hey this should be the MAT to be used for my
//modification of the driver
<SNIP>
Method (HINF, 0, Serialized) // I'm guessing this is like a method in C++ speak ?
{
Acquire (HDMX, 0xFFFF)
If ((HINP == HOUP)) // is this some kind of keyboard 'debounce' logic ?
{
Local0 = Zero
}
Else
{
Local0 = DerefOf (HDAT [HOUP])
HOUP++
HOUP %= 0x20
}
Local1 = (HINP != HOUP)
Release (HDMX)
If (Local1)
{
Notify (HKEY, 0x80) // Status Change , and notify the os.
}
Return (Local0)
}
<SNIP>
}
Unlike a real programming language, “Notify” isnt exacltly clear on what it does, i’m sure its clear to someone a lot more familiar with ACPI. In this case I can immediately see a problem, that the APCI code in the toshiba-laptop code doesn’t deal with this “EisaId (“MAT0019”)”.
A simple test of just adding this to the list of supported drivers, recompiling , reloading the module did not prove fruitful.
TBC.
[root@toughpad dstd]# cat *.dsl |grep MAT0 -B
--
Scope (_SB)
{
Device (MISC)
{
Name (_HID, EisaId ("MAT0021")) // _HID: Hardware ID
--
Scope (_SB)
{
Device (HKEY)
{
Name (_HID, EisaId ("MAT0019")) // _HID: Hardware ID
--
Scope (_SB)
{
Device (WLSW)
{
Mutex (HDMX, 0x00)
Name (_HID, EisaId ("MAT0028")) // _HID: Hardware ID
Three possible “MAT0” devices, “HKEY”
“MISC” could be it, but
HKEY sounds more like keyboard.
Is a child of “WLSW” , after googling around I found that this is likely related to wifi and probaly related to the rfkill switch ( https://lwn.net/Articles/358574/ )
Resources:
https://lwn.net/Articles/367630/ https://www.slideshare.net/suselab/acpi-debugging-from-linux-kernel https://gist.github.com/wmealing/c050d23fd252667a2c420e2172bcefca https://www.kernel.org/doc/Documentation/acpi/debug.txt https://wiki.ubuntu.com/Kernel/Reference/ACPITricksAndTips https://github.com/torvalds/linux/blob/9331b6740f86163908de69f4008e434fe0c27691/drivers/platform/x86/panasonic-laptop.c https://www.intel.com/content/dam/www/public/us/en/documents/articles/acpi-config-power-interface-spec.pdf