[PATCH] platform/x86: Add GETAC MPMD programmable button driver

Zhan Chubukou posted 1 patch 1 week, 3 days ago
MAINTAINERS                       |  6 ++
drivers/platform/x86/Kconfig      | 11 ++++
drivers/platform/x86/Makefile     |  3 +
drivers/platform/x86/getac-mpmd.c | 96 +++++++++++++++++++++++++++++++
4 files changed, 116 insertions(+)
create mode 100644 drivers/platform/x86/getac-mpmd.c
[PATCH] platform/x86: Add GETAC MPMD programmable button driver
Posted by Zhan Chubukou 1 week, 3 days ago
From: chubukou <chubukou@gmail.com>

GETAC rugged laptops (e.g. S410) expose vendor button events through an
ACPI device "MPMD" with hardware ID MTC0303. The Embedded Controller
raises query methods that issue Notify(MPMD, <code>) on programmable /
hotkey button activity. Because no Linux driver binds MTC0303, these
notifies are silently dropped and the buttons appear dead under Linux
(neither libinput nor acpid observe them: they are device notifies, not
generic ACPI events).

Add a minimal ACPI driver that binds MTC0303 and forwards the notifies
as input events through a sparse-keymap. On the S410 (BIOS R1.25) the
programmable P2 button generates Notify(MPMD, 0x97) and is mapped to
KEY_PROG1. Other buttons in the 0xC0..0xCB range (EC queries _Q81.._Q89,
_Q6A, _Q6B) remain unmapped until confirmed on a given model; enable
dynamic-debug to identify them.

Signed-off-by: chubukou <chubukou@gmail.com>
---
 MAINTAINERS                       |  6 ++
 drivers/platform/x86/Kconfig      | 11 ++++
 drivers/platform/x86/Makefile     |  3 +
 drivers/platform/x86/getac-mpmd.c | 96 +++++++++++++++++++++++++++++++
 4 files changed, 116 insertions(+)
 create mode 100644 drivers/platform/x86/getac-mpmd.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ce5c518..9bdabdf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11014,6 +11014,12 @@ F:	Documentation/filesystems/gfs2/
 F:	fs/gfs2/
 F:	include/uapi/linux/gfs2_ondisk.h
 
+GETAC MPMD DRIVER
+M:	chubukou <chubukou@gmail.com>
+L:	platform-driver-x86@vger.kernel.org
+S:	Maintained
+F:	drivers/platform/x86/getac-mpmd.c
+
 GIGABYTE WATERFORCE SENSOR DRIVER
 M:	Aleksa Savic <savicaleksa83@gmail.com>
 L:	linux-hwmon@vger.kernel.org
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index b54b521..2effb96 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -440,6 +440,17 @@ config FUJITSU_TABLET
 
          If you have a Fujitsu convertible or slate, say Y or M here.
 
+config GETAC_MPMD
+	tristate "GETAC MPMD programmable button support"
+	depends on ACPI
+	help
+	  Driver for the GETAC MPMD ACPI device (HID MTC0303) which forwards
+	  Embedded Controller button events (e.g. the programmable P2 button)
+	  as input key events. Without this driver the buttons are silently
+	  dropped and appear dead under Linux.
+
+	  Say Y or M if you have a GETAC rugged laptop (e.g. S410).
+
 config GPD_POCKET_FAN
 	tristate "GPD Pocket Fan Controller support"
 	depends on ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 872ac38..8896da3 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -57,6 +57,9 @@ obj-$(CONFIG_FUJITSU_TABLET)	+= fujitsu-tablet.o
 # GPD
 obj-$(CONFIG_GPD_POCKET_FAN)	+= gpd-pocket-fan.o
 
+# GETAC
+obj-$(CONFIG_GETAC_MPMD)	+= getac-mpmd.o
+
 # Hewlett Packard
 obj-$(CONFIG_X86_PLATFORM_DRIVERS_HP)	+= hp/
 
diff --git a/drivers/platform/x86/getac-mpmd.c b/drivers/platform/x86/getac-mpmd.c
new file mode 100644
index 0000000..0f1ec8b
--- /dev/null
+++ b/drivers/platform/x86/getac-mpmd.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * GETAC MPMD programmable button driver
+ *
+ * GETAC rugged laptops expose vendor events through an ACPI device named
+ * "MPMD" with hardware ID MTC0303. The Embedded Controller raises query
+ * methods that Notify(MPMD, <code>) on programmable / hotkey button
+ * activity. Without a driver bound to MTC0303 these notifies are silently
+ * dropped, so the buttons appear dead under Linux.
+ *
+ * This driver binds MTC0303 and forwards the notifies as input events.
+ *
+ * Observed on GETAC S410 (BIOS R1.25.070520):
+ *   0x97  P2 programmable button (repeats at ~3 Hz while held)
+ *
+ * The 0xC0..0xCB range is generated by EC query methods _Q81.._Q89, _Q6A
+ * and _Q6B and is left as KEY_UNKNOWN until a button is confirmed; enable
+ * module dynamic-debug to identify further buttons on a given model.
+ *
+ * Copyright (C) 2026 chubukou <chubukou@gmail.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/module.h>
+
+struct getac_mpmd_priv {
+	struct input_dev *input;
+};
+
+static const struct key_entry getac_mpmd_keymap[] = {
+	{ KE_KEY, 0x97, { KEY_PROG1 } },		/* P2 programmable button */
+	{ KE_END, 0 }
+};
+
+static void getac_mpmd_notify(struct acpi_device *adev, u32 event)
+{
+	struct getac_mpmd_priv *priv = acpi_driver_data(adev);
+
+	if (!sparse_keymap_report_event(priv->input, event, 1, true))
+		dev_dbg(&adev->dev, "unknown notify event 0x%02x\n", event);
+}
+
+static int getac_mpmd_add(struct acpi_device *adev)
+{
+	struct getac_mpmd_priv *priv;
+	struct input_dev *input;
+	int ret;
+
+	priv = devm_kzalloc(&adev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	input = devm_input_allocate_device(&adev->dev);
+	if (!input)
+		return -ENOMEM;
+
+	input->name = "GETAC MPMD programmable buttons";
+	input->phys = "getac-mpmd/input0";
+	input->id.bustype = BUS_HOST;
+
+	ret = sparse_keymap_setup(input, getac_mpmd_keymap, NULL);
+	if (ret)
+		return ret;
+
+	ret = input_register_device(input);
+	if (ret)
+		return ret;
+
+	priv->input = input;
+	adev->driver_data = priv;
+	return 0;
+}
+
+static const struct acpi_device_id getac_mpmd_ids[] = {
+	{ "MTC0303" },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, getac_mpmd_ids);
+
+static struct acpi_driver getac_mpmd_driver = {
+	.name = "getac_mpmd",
+	.class = "getac",
+	.ids = getac_mpmd_ids,
+	.ops = {
+		.add = getac_mpmd_add,
+		.notify = getac_mpmd_notify,
+	},
+};
+
+module_acpi_driver(getac_mpmd_driver);
+
+MODULE_AUTHOR("chubukou <chubukou@gmail.com>");
+MODULE_DESCRIPTION("GETAC MPMD (MTC0303) programmable button driver");
+MODULE_LICENSE("GPL");
-- 
2.55.0
Re: [PATCH] platform/x86: Add GETAC MPMD programmable button driver
Posted by Ilpo Järvinen 4 days, 10 hours ago
On Wed, 15 Jul 2026, Zhan Chubukou wrote:

> From: chubukou <chubukou@gmail.com>
> 
> GETAC rugged laptops (e.g. S410) expose vendor button events through an
> ACPI device "MPMD" with hardware ID MTC0303. The Embedded Controller
> raises query methods that issue Notify(MPMD, <code>) on programmable /
> hotkey button activity. Because no Linux driver binds MTC0303, these
> notifies are silently dropped and the buttons appear dead under Linux
> (neither libinput nor acpid observe them: they are device notifies, not
> generic ACPI events).
> 
> Add a minimal ACPI driver that binds MTC0303 and forwards the notifies
> as input events through a sparse-keymap. On the S410 (BIOS R1.25) the
> programmable P2 button generates Notify(MPMD, 0x97) and is mapped to
> KEY_PROG1. Other buttons in the 0xC0..0xCB range (EC queries _Q81.._Q89,
> _Q6A, _Q6B) remain unmapped until confirmed on a given model; enable
> dynamic-debug to identify them.
> 
> Signed-off-by: chubukou <chubukou@gmail.com>

We need a read name here. For more information, please see 
Documentation/process/submitting-patches.rst

> ---
>  MAINTAINERS                       |  6 ++
>  drivers/platform/x86/Kconfig      | 11 ++++
>  drivers/platform/x86/Makefile     |  3 +
>  drivers/platform/x86/getac-mpmd.c | 96 +++++++++++++++++++++++++++++++
>  4 files changed, 116 insertions(+)
>  create mode 100644 drivers/platform/x86/getac-mpmd.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index ce5c518..9bdabdf 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11014,6 +11014,12 @@ F:	Documentation/filesystems/gfs2/
>  F:	fs/gfs2/
>  F:	include/uapi/linux/gfs2_ondisk.h
>  
> +GETAC MPMD DRIVER
> +M:	chubukou <chubukou@gmail.com>
> +L:	platform-driver-x86@vger.kernel.org
> +S:	Maintained
> +F:	drivers/platform/x86/getac-mpmd.c
> +
>  GIGABYTE WATERFORCE SENSOR DRIVER
>  M:	Aleksa Savic <savicaleksa83@gmail.com>
>  L:	linux-hwmon@vger.kernel.org
> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
> index b54b521..2effb96 100644
> --- a/drivers/platform/x86/Kconfig
> +++ b/drivers/platform/x86/Kconfig
> @@ -440,6 +440,17 @@ config FUJITSU_TABLET
>  
>           If you have a Fujitsu convertible or slate, say Y or M here.
>  
> +config GETAC_MPMD
> +	tristate "GETAC MPMD programmable button support"
> +	depends on ACPI
> +	help
> +	  Driver for the GETAC MPMD ACPI device (HID MTC0303) which forwards
> +	  Embedded Controller button events (e.g. the programmable P2 button)
> +	  as input key events. Without this driver the buttons are silently
> +	  dropped and appear dead under Linux.
> +
> +	  Say Y or M if you have a GETAC rugged laptop (e.g. S410).
> +
>  config GPD_POCKET_FAN
>  	tristate "GPD Pocket Fan Controller support"
>  	depends on ACPI
> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
> index 872ac38..8896da3 100644
> --- a/drivers/platform/x86/Makefile
> +++ b/drivers/platform/x86/Makefile
> @@ -57,6 +57,9 @@ obj-$(CONFIG_FUJITSU_TABLET)	+= fujitsu-tablet.o
>  # GPD
>  obj-$(CONFIG_GPD_POCKET_FAN)	+= gpd-pocket-fan.o
>  
> +# GETAC
> +obj-$(CONFIG_GETAC_MPMD)	+= getac-mpmd.o
> +
>  # Hewlett Packard
>  obj-$(CONFIG_X86_PLATFORM_DRIVERS_HP)	+= hp/
>  
> diff --git a/drivers/platform/x86/getac-mpmd.c b/drivers/platform/x86/getac-mpmd.c
> new file mode 100644
> index 0000000..0f1ec8b
> --- /dev/null
> +++ b/drivers/platform/x86/getac-mpmd.c
> @@ -0,0 +1,96 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * GETAC MPMD programmable button driver
> + *
> + * GETAC rugged laptops expose vendor events through an ACPI device named
> + * "MPMD" with hardware ID MTC0303. The Embedded Controller raises query
> + * methods that Notify(MPMD, <code>) on programmable / hotkey button
> + * activity. Without a driver bound to MTC0303 these notifies are silently
> + * dropped, so the buttons appear dead under Linux.
> + *
> + * This driver binds MTC0303 and forwards the notifies as input events.
> + *
> + * Observed on GETAC S410 (BIOS R1.25.070520):
> + *   0x97  P2 programmable button (repeats at ~3 Hz while held)
> + *
> + * The 0xC0..0xCB range is generated by EC query methods _Q81.._Q89, _Q6A
> + * and _Q6B and is left as KEY_UNKNOWN until a button is confirmed; enable
> + * module dynamic-debug to identify further buttons on a given model.
> + *
> + * Copyright (C) 2026 chubukou <chubukou@gmail.com>
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/input.h>
> +#include <linux/input/sparse-keymap.h>

You probably need something in Kconfig for these?

> +#include <linux/module.h>
> +
> +struct getac_mpmd_priv {
> +	struct input_dev *input;
> +};
> +
> +static const struct key_entry getac_mpmd_keymap[] = {
> +	{ KE_KEY, 0x97, { KEY_PROG1 } },		/* P2 programmable button */
> +	{ KE_END, 0 }
> +};
> +
> +static void getac_mpmd_notify(struct acpi_device *adev, u32 event)
> +{
> +	struct getac_mpmd_priv *priv = acpi_driver_data(adev);
> +
> +	if (!sparse_keymap_report_event(priv->input, event, 1, true))
> +		dev_dbg(&adev->dev, "unknown notify event 0x%02x\n", event);

Add include for dev_dbg()

> +}
> +
> +static int getac_mpmd_add(struct acpi_device *adev)
> +{
> +	struct getac_mpmd_priv *priv;
> +	struct input_dev *input;
> +	int ret;
> +
> +	priv = devm_kzalloc(&adev->dev, sizeof(*priv), GFP_KERNEL);

Please add linux/device.h include for this.

> +	if (!priv)
> +		return -ENOMEM;
> +
> +	input = devm_input_allocate_device(&adev->dev);
> +	if (!input)
> +		return -ENOMEM;
> +
> +	input->name = "GETAC MPMD programmable buttons";
> +	input->phys = "getac-mpmd/input0";
> +	input->id.bustype = BUS_HOST;
> +
> +	ret = sparse_keymap_setup(input, getac_mpmd_keymap, NULL);
> +	if (ret)
> +		return ret;
> +
> +	ret = input_register_device(input);
> +	if (ret)
> +		return ret;
> +
> +	priv->input = input;
> +	adev->driver_data = priv;

Once you've converted to platform_driver (see below), please use the 
accessor to set drvdata.

> +	return 0;
> +}
> +
> +static const struct acpi_device_id getac_mpmd_ids[] = {
> +	{ "MTC0303" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(acpi, getac_mpmd_ids);
> +
> +static struct acpi_driver getac_mpmd_driver = {

Please don't add new acpi_drivers anymore. Rafael is trying to get rid all 
of them.

> +	.name = "getac_mpmd",
> +	.class = "getac",
> +	.ids = getac_mpmd_ids,
> +	.ops = {
> +		.add = getac_mpmd_add,
> +		.notify = getac_mpmd_notify,
> +	},
> +};
> +
> +module_acpi_driver(getac_mpmd_driver);
> +
> +MODULE_AUTHOR("chubukou <chubukou@gmail.com>");
> +MODULE_DESCRIPTION("GETAC MPMD (MTC0303) programmable button driver");
> +MODULE_LICENSE("GPL");
> 

-- 
 i.