Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH v2 9/9] power: supply: Add charger driver for Asus Transformers
From: Svyatoslav Ryhel @ 2026-02-09 10:44 UTC (permalink / raw)
  To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Dmitry Torokhov, Pavel Machek, Arnd Bergmann, Greg Kroah-Hartman,
	Sebastian Reichel, Svyatoslav Ryhel, Michał Mirosław,
	Ion Agorria
  Cc: devicetree, linux-kernel, linux-input, linux-leds, linux-pm
In-Reply-To: <20260209104407.116426-1-clamor95@gmail.com>

From: Michał Mirosław <mirq-linux@rere.qmqm.pl>

Add support for charger detection capabilities found in the embedded
controller of ASUS Transformer devices.

Suggested-by: Maxim Schwalm <maxim.schwalm@gmail.com>
Suggested-by: Svyatoslav Ryhel <clamor95@gmail.com>
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
 drivers/power/supply/Kconfig           |  11 ++
 drivers/power/supply/Makefile          |   1 +
 drivers/power/supply/asus-ec-charger.c | 206 +++++++++++++++++++++++++
 3 files changed, 218 insertions(+)
 create mode 100644 drivers/power/supply/asus-ec-charger.c

diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig
index bcf6a23858be..43b902a12795 100644
--- a/drivers/power/supply/Kconfig
+++ b/drivers/power/supply/Kconfig
@@ -497,6 +497,17 @@ config CHARGER_88PM860X
 	help
 	  Say Y here to enable charger for Marvell 88PM860x chip.
 
+config CHARGER_ASUSEC
+	tristate "Asus Transformer's charger driver"
+	depends on MFD_ASUSEC
+	help
+	  Say Y here to enable support AC plug detection on Asus Transformer
+	  Dock.
+
+	  This sub-driver supports charger detection mechanism found in Asus
+	  Transformer tablets and mobile docks and controlled by special
+	  embedded controller.
+
 config CHARGER_PF1550
 	tristate "NXP PF1550 battery charger driver"
 	depends on MFD_PF1550
diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile
index 0a2cbfa96ed9..b93848227f50 100644
--- a/drivers/power/supply/Makefile
+++ b/drivers/power/supply/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_BATTERY_88PM860X)	+= 88pm860x_battery.o
 obj-$(CONFIG_CHARGER_ADP5061)	+= adp5061.o
 obj-$(CONFIG_BATTERY_ACT8945A)	+= act8945a_charger.o
 obj-$(CONFIG_BATTERY_ASUSEC)	+= asus-ec-battery.o
+obj-$(CONFIG_CHARGER_ASUSEC)	+= asus-ec-charger.o
 obj-$(CONFIG_BATTERY_AXP20X)	+= axp20x_battery.o
 obj-$(CONFIG_CHARGER_AXP20X)	+= axp20x_ac_power.o
 obj-$(CONFIG_BATTERY_CHAGALL)	+= chagall-battery.o
diff --git a/drivers/power/supply/asus-ec-charger.c b/drivers/power/supply/asus-ec-charger.c
new file mode 100644
index 000000000000..bcf798432755
--- /dev/null
+++ b/drivers/power/supply/asus-ec-charger.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * ASUS EC driver - charger monitoring
+ */
+
+#include <linux/err.h>
+#include <linux/mfd/asus-ec.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/property.h>
+
+struct asus_ec_charger_data {
+	struct notifier_block nb;
+	const struct asusec_info *ec;
+	struct power_supply *psy;
+	struct power_supply_desc psy_desc;
+};
+
+static enum power_supply_property asus_ec_charger_properties[] = {
+	POWER_SUPPLY_PROP_USB_TYPE,
+	POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR,
+	POWER_SUPPLY_PROP_ONLINE,
+	POWER_SUPPLY_PROP_MODEL_NAME,
+};
+
+static int asus_ec_charger_get_property(struct power_supply *psy,
+					enum power_supply_property psp,
+					union power_supply_propval *val)
+{
+	struct asus_ec_charger_data *priv = power_supply_get_drvdata(psy);
+	enum power_supply_usb_type psu;
+	int ret;
+	u64 ctl;
+
+	ret = asus_ec_get_ctl(priv->ec, &ctl);
+	if (ret)
+		return ret;
+
+	switch (ctl & (ASUSEC_CTL_FULL_POWER_SOURCE | ASUSEC_CTL_DIRECT_POWER_SOURCE)) {
+	case ASUSEC_CTL_FULL_POWER_SOURCE:
+		psu = POWER_SUPPLY_USB_TYPE_CDP;	/* DOCK */
+		break;
+	case ASUSEC_CTL_DIRECT_POWER_SOURCE:
+		psu = POWER_SUPPLY_USB_TYPE_SDP;	/* USB */
+		break;
+	case 0:
+		psu = POWER_SUPPLY_USB_TYPE_UNKNOWN;	/* no power source connected */
+		break;
+	default:
+		psu = POWER_SUPPLY_USB_TYPE_ACA;	/* power adapter */
+		break;
+	}
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = psu != POWER_SUPPLY_USB_TYPE_UNKNOWN;
+		return 0;
+
+	case POWER_SUPPLY_PROP_USB_TYPE:
+		val->intval = psu;
+		return 0;
+
+	case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
+		if (ctl & ASUSEC_CTL_TEST_DISCHARGE)
+			val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE;
+		else if (ctl & ASUSEC_CTL_USB_CHARGE)
+			val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO;
+		else
+			val->intval = POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE;
+		return 0;
+
+	case POWER_SUPPLY_PROP_MODEL_NAME:
+		val->strval = priv->ec->model;
+		return 0;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static int asus_ec_charger_set_property(struct power_supply *psy,
+					enum power_supply_property psp,
+					const union power_supply_propval *val)
+{
+	struct asus_ec_charger_data *priv = power_supply_get_drvdata(psy);
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
+		switch ((enum power_supply_charge_behaviour)val->intval) {
+		case POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO:
+			return asus_ec_update_ctl(priv->ec,
+				ASUSEC_CTL_TEST_DISCHARGE | ASUSEC_CTL_USB_CHARGE,
+				ASUSEC_CTL_USB_CHARGE);
+
+		case POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE:
+			return asus_ec_clear_ctl_bits(priv->ec,
+				ASUSEC_CTL_TEST_DISCHARGE | ASUSEC_CTL_USB_CHARGE);
+
+		case POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE:
+			return asus_ec_update_ctl(priv->ec,
+				ASUSEC_CTL_TEST_DISCHARGE | ASUSEC_CTL_USB_CHARGE,
+				ASUSEC_CTL_TEST_DISCHARGE);
+		default:
+			return -EINVAL;
+		}
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static int asus_ec_charger_property_is_writeable(struct power_supply *psy,
+						 enum power_supply_property psp)
+{
+	switch (psp) {
+	case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct power_supply_desc asus_ec_charger_desc = {
+	.name = "asus-ec-charger",
+	.type = POWER_SUPPLY_TYPE_USB,
+	.charge_behaviours = BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) |
+			     BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE) |
+			     BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE),
+	.usb_types = BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN) |
+		     BIT(POWER_SUPPLY_USB_TYPE_SDP) |
+		     BIT(POWER_SUPPLY_USB_TYPE_CDP) |
+		     BIT(POWER_SUPPLY_USB_TYPE_ACA),
+	.properties = asus_ec_charger_properties,
+	.num_properties = ARRAY_SIZE(asus_ec_charger_properties),
+	.get_property = asus_ec_charger_get_property,
+	.set_property = asus_ec_charger_set_property,
+	.property_is_writeable = asus_ec_charger_property_is_writeable,
+	.no_thermal = true,
+};
+
+static int asus_ec_charger_notify(struct notifier_block *nb,
+				  unsigned long action, void *data)
+{
+	struct asus_ec_charger_data *priv =
+		container_of(nb, struct asus_ec_charger_data, nb);
+
+	switch (action) {
+	case ASUSEC_SMI_ACTION(POWER_NOTIFY):
+	case ASUSEC_SMI_ACTION(ADAPTER_EVENT):
+		power_supply_changed(priv->psy);
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static int asus_ec_charger_probe(struct platform_device *pdev)
+{
+	struct asus_ec_charger_data *priv;
+	struct device *dev = &pdev->dev;
+	struct power_supply_config cfg = { };
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, priv);
+	priv->ec = cell_to_ec(pdev);
+
+	cfg.fwnode = dev_fwnode(dev);
+	cfg.drv_data = priv;
+
+	memcpy(&priv->psy_desc, &asus_ec_charger_desc, sizeof(priv->psy_desc));
+	priv->psy_desc.name = devm_kasprintf(dev, GFP_KERNEL, "%s-charger",
+					     priv->ec->name);
+
+	priv->psy = devm_power_supply_register(dev, &priv->psy_desc, &cfg);
+	if (IS_ERR(priv->psy))
+		return dev_err_probe(dev, PTR_ERR(priv->psy),
+				     "Failed to register power supply\n");
+
+	priv->nb.notifier_call = asus_ec_charger_notify;
+
+	return devm_asus_ec_register_notifier(pdev, &priv->nb);
+}
+
+static const struct of_device_id asus_ec_charger_match[] = {
+	{ .compatible = "asus,ec-charger" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, asus_ec_charger_match);
+
+static struct platform_driver asus_ec_charger_driver = {
+	.driver = {
+		.name = "asus-ec-charger",
+		.of_match_table = asus_ec_charger_match,
+	},
+	.probe = asus_ec_charger_probe,
+};
+module_platform_driver(asus_ec_charger_driver);
+
+MODULE_AUTHOR("Michał Mirosław <mirq-linux@rere.qmqm.pl>");
+MODULE_DESCRIPTION("ASUS Transformer Pad battery charger driver");
+MODULE_LICENSE("GPL");
-- 
2.51.0


^ permalink raw reply related

* Re: [PATCH] usbhid: tolerate intermittent errors
From: Liam Mitchell @ 2026-02-09 10:49 UTC (permalink / raw)
  To: Oliver Neukum
  Cc: Jiri Kosina, Benjamin Tissoires, Alan Stern, linux-usb,
	linux-input, linux-kernel
In-Reply-To: <a31763aa-77af-4e13-8708-b007ed53277c@suse.com>

On Mon, 9 Feb 2026 at 11:06, Oliver Neukum <oneukum@suse.com> wrote:
> On 08.02.26 18:10, Liam Mitchell wrote:
> > Modifies the usbhid error handling logic to better handle intermittent
> > errors like EPROTO, which should only need resubmission of URBs and not
> > full device reset.
> >
> > Reduces initial retry delay from 13ms to 1ms. The faster the URB is
> > resubmitted, the lower the chance that user events will be missed.
>
> in this case I have to ask the obvious question: Why wait at all?
> It would seem to me that if you have spurious or intermittent errors
> the right time to retry is immediately.

Agreed.

This patch is intentionally small because I wasn't sure if a more
comprehensive fix is wanted.

Regards,
Liam

^ permalink raw reply

* [PATCH v3 0/3] Add support for Awinic AW86938 haptic driver
From: Griffin Kroah-Hartman @ 2026-02-09 12:59 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio, Luca Weiss
  Cc: linux-input, devicetree, linux-kernel, linux-arm-msm,
	Griffin Kroah-Hartman, Dmitry Baryshkov, Konrad Dybcio

Add devicetree bindings and a driver for the AW86938 haptic driver chip,
and add it to the devicetree for the Fairphone 6 smartphone.

This driver is very similar to the AW86927, and shares many core
features.

Signed-off-by: Griffin Kroah-Hartman <griffin.kroah@fairphone.com>
---
Changes in v3:
- Changed how compatibility was handled according to feedback
- Added reset gpio config for vibrator node
- Link to v2: https://lore.kernel.org/r/20260128-aw86938-driver-v2-0-b51ee086aaf5@fairphone.com

Changes in v2:
- Added AW86938 specific registers
- Added chip model enum to differentiate chips
- Link to v1: https://lore.kernel.org/r/20251204-aw86938-driver-v1-0-ebd71868df3a@fairphone.com

---
Griffin Kroah-Hartman (3):
      dt-bindings: input: awinic,aw86927: Add Awinic AW86938
      Input: aw86938 - add driver for Awinic AW86938
      arm64: dts: qcom: milos-fairphone-fp6: Add vibrator support

 .../devicetree/bindings/input/awinic,aw86927.yaml  |  7 ++-
 arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts   | 26 ++++++++++-
 drivers/input/misc/aw86927.c                       | 54 ++++++++++++++++++----
 3 files changed, 76 insertions(+), 11 deletions(-)
---
base-commit: 0364de6be161e2360cbb1f26d5aff5b343ef7bb0
change-id: 20251113-aw86938-driver-b4fa0d3228a2

Best regards,
-- 
Griffin Kroah-Hartman <griffin.kroah@fairphone.com>


^ permalink raw reply

* [PATCH v3 1/3] dt-bindings: input: awinic,aw86927: Add Awinic AW86938
From: Griffin Kroah-Hartman @ 2026-02-09 12:59 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio, Luca Weiss
  Cc: linux-input, devicetree, linux-kernel, linux-arm-msm,
	Griffin Kroah-Hartman
In-Reply-To: <20260209-aw86938-driver-v3-0-5c79cff30492@fairphone.com>

Add bindings for the Awinic AW86938 haptic chip which can be found in
smartphones. These two chips require a similar devicetree configuration,
but have a register layout that's not 100% compatible.
Still, we can document them in the same file.

Signed-off-by: Griffin Kroah-Hartman <griffin.kroah@fairphone.com>
---
 Documentation/devicetree/bindings/input/awinic,aw86927.yaml | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/input/awinic,aw86927.yaml b/Documentation/devicetree/bindings/input/awinic,aw86927.yaml
index b7252916bd727486c1a98913d4ec3ef12422e4bd..bd74b81488f61d72b675b5701b321b30b3430be0 100644
--- a/Documentation/devicetree/bindings/input/awinic,aw86927.yaml
+++ b/Documentation/devicetree/bindings/input/awinic,aw86927.yaml
@@ -11,7 +11,12 @@ maintainers:
 
 properties:
   compatible:
-    const: awinic,aw86927
+    oneOf:
+      - const: awinic,aw86927
+      - items:
+          - enum:
+              - awinic,aw86938
+          - const: awinic,aw86927
 
   reg:
     maxItems: 1

-- 
2.43.0


^ permalink raw reply related

* [PATCH v3 3/3] arm64: dts: qcom: milos-fairphone-fp6: Add vibrator support
From: Griffin Kroah-Hartman @ 2026-02-09 12:59 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio, Luca Weiss
  Cc: linux-input, devicetree, linux-kernel, linux-arm-msm,
	Griffin Kroah-Hartman, Dmitry Baryshkov, Konrad Dybcio
In-Reply-To: <20260209-aw86938-driver-v3-0-5c79cff30492@fairphone.com>

Add the required node for haptic playback (Awinic AW86938)

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Griffin Kroah-Hartman <griffin.kroah@fairphone.com>
---
 arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts | 26 +++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts b/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts
index 52895dd9e4fa117aef6822df230ebf644e5f02ba..324d18d9900881a840806ada84e33fe9664296a0 100644
--- a/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts
+++ b/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts
@@ -625,7 +625,17 @@ vreg_l7p: ldo7 {
 	};
 
 	/* VL53L3 ToF @ 0x29 */
-	/* AW86938FCR vibrator @ 0x5a */
+
+	vibrator@5a {
+		compatible = "awinic,aw86938", "awinic,aw86927";
+		reg = <0x5a>;
+
+		interrupts-extended = <&tlmm 80 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&tlmm 78 GPIO_ACTIVE_LOW>;
+
+		pinctrl-0 = <&aw86938_int_default>, <&aw86938_reset_default>;
+		pinctrl-names = "default";
+	};
 };
 
 &pm8550vs_c {
@@ -755,6 +765,20 @@ sdc2_card_det_n: sdc2-card-det-state {
 		bias-pull-up;
 	};
 
+	aw86938_reset_default: aw86938-reset-default-state {
+		pins = "gpio78";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+	};
+
+	aw86938_int_default: aw86938-int-default-state {
+		pins = "gpio80";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-up;
+	};
+
 	pm8008_int_default: pm8008-int-default-state {
 		pins = "gpio125";
 		function = "gpio";

-- 
2.43.0


^ permalink raw reply related

* [PATCH v3 2/3] Input: aw86938 - add driver for Awinic AW86938
From: Griffin Kroah-Hartman @ 2026-02-09 12:59 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Bjorn Andersson, Konrad Dybcio, Luca Weiss
  Cc: linux-input, devicetree, linux-kernel, linux-arm-msm,
	Griffin Kroah-Hartman
In-Reply-To: <20260209-aw86938-driver-v3-0-5c79cff30492@fairphone.com>

Add support for the I2C-connected Awinic AW86938 LRA haptic driver.

The AW86938 has a similar but slightly different register layout. In
particular, the boost mode register values.
The AW86938 also has some extra features that aren't implemented
in this driver yet.

Signed-off-by: Griffin Kroah-Hartman <griffin.kroah@fairphone.com>
---
 drivers/input/misc/aw86927.c | 54 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 45 insertions(+), 9 deletions(-)

diff --git a/drivers/input/misc/aw86927.c b/drivers/input/misc/aw86927.c
index 8ad361239cfe3a888628b15e4dbdeed0c9ca3d1a..678526ef2bb7da654734e8f53ad8442c556f209b 100644
--- a/drivers/input/misc/aw86927.c
+++ b/drivers/input/misc/aw86927.c
@@ -43,6 +43,12 @@
 #define AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK	GENMASK(6, 0)
 #define AW86927_PLAYCFG1_BST_8500MV		0x50
 
+#define AW86938_PLAYCFG1_REG			0x06
+#define AW86938_PLAYCFG1_BST_MODE_MASK		GENMASK(5, 5)
+#define AW86938_PLAYCFG1_BST_MODE_BYPASS	0
+#define AW86938_PLAYCFG1_BST_VOUT_VREFSET_MASK	GENMASK(4, 0)
+#define AW86938_PLAYCFG1_BST_7000MV		0x11
+
 #define AW86927_PLAYCFG2_REG			0x07
 
 #define AW86927_PLAYCFG3_REG			0x08
@@ -140,6 +146,7 @@
 #define AW86927_CHIPIDH_REG			0x57
 #define AW86927_CHIPIDL_REG			0x58
 #define AW86927_CHIPID				0x9270
+#define AW86938_CHIPID				0x9380
 
 #define AW86927_TMCFG_REG			0x5b
 #define AW86927_TMCFG_UNLOCK			0x7d
@@ -173,7 +180,13 @@ enum aw86927_work_mode {
 	AW86927_RAM_MODE,
 };
 
+enum aw86927_model {
+	AW86927,
+	AW86938,
+};
+
 struct aw86927_data {
+	enum aw86927_model model;
 	struct work_struct play_work;
 	struct device *dev;
 	struct input_dev *input_dev;
@@ -377,7 +390,7 @@ static int aw86927_play_sine(struct aw86927_data *haptics)
 		return err;
 
 	/* set gain to value lower than 0x80 to avoid distorted playback */
-	err = regmap_write(haptics->regmap, AW86927_PLAYCFG2_REG, 0x7c);
+	err = regmap_write(haptics->regmap, AW86927_PLAYCFG2_REG, 0x45);
 	if (err)
 		return err;
 
@@ -565,13 +578,26 @@ static int aw86927_haptic_init(struct aw86927_data *haptics)
 	if (err)
 		return err;
 
-	err = regmap_update_bits(haptics->regmap,
-				 AW86927_PLAYCFG1_REG,
-				 AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK,
-				 FIELD_PREP(AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK,
-					    AW86927_PLAYCFG1_BST_8500MV));
-	if (err)
-		return err;
+	switch (haptics->model) {
+	case AW86927:
+		err = regmap_update_bits(haptics->regmap,
+				AW86927_PLAYCFG1_REG,
+				AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK,
+				FIELD_PREP(AW86927_PLAYCFG1_BST_VOUT_VREFSET_MASK,
+					AW86927_PLAYCFG1_BST_8500MV));
+		if (err)
+			return err;
+		break;
+	case AW86938:
+		err = regmap_update_bits(haptics->regmap,
+				AW86938_PLAYCFG1_REG,
+				AW86938_PLAYCFG1_BST_VOUT_VREFSET_MASK,
+				FIELD_PREP(AW86938_PLAYCFG1_BST_VOUT_VREFSET_MASK,
+					AW86938_PLAYCFG1_BST_7000MV));
+		if (err)
+			return err;
+		break;
+	}
 
 	err = regmap_update_bits(haptics->regmap,
 				 AW86927_PLAYCFG3_REG,
@@ -599,6 +625,9 @@ static int aw86927_ram_init(struct aw86927_data *haptics)
 				 FIELD_PREP(AW86927_SYSCTRL3_EN_RAMINIT_MASK,
 					    AW86927_SYSCTRL3_EN_RAMINIT_ON));
 
+	/* AW86938 wants a 1ms delay here */
+	usleep_range(1000, 1500);
+
 	/* Set base address for the start of the SRAM waveforms */
 	err = regmap_write(haptics->regmap,
 			   AW86927_BASEADDRH_REG, AW86927_BASEADDRH_VAL);
@@ -717,7 +746,14 @@ static int aw86927_detect(struct aw86927_data *haptics)
 
 	chip_id = be16_to_cpu(read_buf);
 
-	if (chip_id != AW86927_CHIPID) {
+	switch (chip_id) {
+	case AW86927_CHIPID:
+		haptics->model = AW86927;
+		break;
+	case AW86938_CHIPID:
+		haptics->model = AW86938;
+		break;
+	default:
 		dev_err(haptics->dev, "Unexpected CHIPID value 0x%x\n", chip_id);
 		return -ENODEV;
 	}

-- 
2.43.0


^ permalink raw reply related

* [PATCH v2 0/3] monaco: Add PMM8654AU PON support
From: Rakesh Kota @ 2026-02-09 13:23 UTC (permalink / raw)
  To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Vinod Koul, Dmitry Torokhov, Courtney Cavin, Bjorn Andersson,
	Konrad Dybcio
  Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, linux-input,
	Rakesh Kota

This patch series updates the PON power and reset dt-bindings and
device tree to add support for PON power and reset keys on the 
Monaco platform.

Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
---
Changes in v2:
- Introduces PMM8654AU compatible strings as suggested by Konrad Dybcio.

---
Rakesh Kota (3):
      dt-bindings: power: reset: qcom-pon: Add new compatible PMM8654AU
      dt-bindings: input: qcom,pm8941-pwrkey: Document PMM8654AU
      arm64: dts: qcom: monaco-pmics: Add PON power key and reset inputs

 .../bindings/input/qcom,pm8941-pwrkey.yaml           | 17 ++++++++++++-----
 .../devicetree/bindings/power/reset/qcom,pon.yaml    | 16 ++++++++++------
 arch/arm64/boot/dts/qcom/monaco-pmics.dtsi           | 20 ++++++++++++++++++++
 3 files changed, 42 insertions(+), 11 deletions(-)
---
base-commit: 9845cf73f7db6094c0d8419d6adb848028f4a921
change-id: 20260206-add_pwrkey_and_resin-c5dcf4e3f36d

Best regards,
-- 
Rakesh Kota <rakesh.kota@oss.qualcomm.com>


^ permalink raw reply

* [PATCH v2 1/3] dt-bindings: power: reset: qcom-pon: Add new compatible PMM8654AU
From: Rakesh Kota @ 2026-02-09 13:23 UTC (permalink / raw)
  To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Vinod Koul, Dmitry Torokhov, Courtney Cavin, Bjorn Andersson,
	Konrad Dybcio
  Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, linux-input,
	Rakesh Kota
In-Reply-To: <20260209-add_pwrkey_and_resin-v2-0-f944d87b9a93@oss.qualcomm.com>

Add the compatible string "qcom,pmm8654au-pon" for the PMM8654AU PMIC.
The PON peripheral on PMM8654AU is compatible with PMK8350, so it is
documented as a fallback to "qcom,pmk8350-pon".

While PMM8654AU supports additional registers compared to the baseline,
there is currently no active use case for these features. This specific
compatible string reserves the identifier for future hardware-specific
handling if required.

Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
---
 .../devicetree/bindings/power/reset/qcom,pon.yaml        | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/power/reset/qcom,pon.yaml b/Documentation/devicetree/bindings/power/reset/qcom,pon.yaml
index 979a377cb4ffd577bfa51b9a3cd089acc202de0c..14b85b0d97da12c756cfe2ce33853501ba4ca46c 100644
--- a/Documentation/devicetree/bindings/power/reset/qcom,pon.yaml
+++ b/Documentation/devicetree/bindings/power/reset/qcom,pon.yaml
@@ -17,12 +17,16 @@ description: |
 
 properties:
   compatible:
-    enum:
-      - qcom,pm8916-pon
-      - qcom,pm8941-pon
-      - qcom,pms405-pon
-      - qcom,pm8998-pon
-      - qcom,pmk8350-pon
+    oneOf:
+      - enum:
+          - qcom,pm8916-pon
+          - qcom,pm8941-pon
+          - qcom,pms405-pon
+          - qcom,pm8998-pon
+          - qcom,pmk8350-pon
+      - items:
+          - const: qcom,pmm8654au-pon
+          - const: qcom,pmk8350-pon
 
   reg:
     description: |

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 2/3] dt-bindings: input: qcom,pm8941-pwrkey: Document PMM8654AU
From: Rakesh Kota @ 2026-02-09 13:23 UTC (permalink / raw)
  To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Vinod Koul, Dmitry Torokhov, Courtney Cavin, Bjorn Andersson,
	Konrad Dybcio
  Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, linux-input,
	Rakesh Kota
In-Reply-To: <20260209-add_pwrkey_and_resin-v2-0-f944d87b9a93@oss.qualcomm.com>

Add compatible strings for PMM8654AU power key and resin support.
These blocks are compatible with PMK8350, so use that as the
fallback.

Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
---
 .../devicetree/bindings/input/qcom,pm8941-pwrkey.yaml   | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.yaml b/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.yaml
index f978cf965a4d497cb7a4c670cea368c3ac70b67e..f2543d6faefdc42c36c4b9851e0f9532e73dd02a 100644
--- a/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.yaml
+++ b/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.yaml
@@ -12,11 +12,18 @@ maintainers:
 
 properties:
   compatible:
-    enum:
-      - qcom,pm8941-pwrkey
-      - qcom,pm8941-resin
-      - qcom,pmk8350-pwrkey
-      - qcom,pmk8350-resin
+    oneOf:
+      - enum:
+          - qcom,pm8941-pwrkey
+          - qcom,pm8941-resin
+          - qcom,pmk8350-pwrkey
+          - qcom,pmk8350-resin
+      - items:
+          - const: qcom,pmm8654au-pwrkey
+          - const: qcom,pmk8350-pwrkey
+      - items:
+          - const: qcom,pmm8654au-resin
+          - const: qcom,pmk8350-resin
 
   interrupts:
     maxItems: 1

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 3/3] arm64: dts: qcom: monaco-pmics: Add PON power key and reset inputs
From: Rakesh Kota @ 2026-02-09 13:23 UTC (permalink / raw)
  To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Vinod Koul, Dmitry Torokhov, Courtney Cavin, Bjorn Andersson,
	Konrad Dybcio
  Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, linux-input,
	Rakesh Kota
In-Reply-To: <20260209-add_pwrkey_and_resin-v2-0-f944d87b9a93@oss.qualcomm.com>

Add the Power On (PON) peripheral with power key and reset input
support for the PMM8654AU PMIC on Monaco platforms.

Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/monaco-pmics.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/monaco-pmics.dtsi b/arch/arm64/boot/dts/qcom/monaco-pmics.dtsi
index e990d7367719beaa9e0cea87d9c183ae18c3ebc8..182c2339bb11af40275050a36c4688227e89497a 100644
--- a/arch/arm64/boot/dts/qcom/monaco-pmics.dtsi
+++ b/arch/arm64/boot/dts/qcom/monaco-pmics.dtsi
@@ -13,6 +13,26 @@ pmm8620au_0: pmic@0 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 
+		pmm8654au_0_pon: pon@1200 {
+			compatible = "qcom,pmm8654au-pon", "qcom,pmk8350-pon";
+			reg = <0x1200>, <0x800>;
+			reg-names = "hlos", "pbs";
+
+			pmm8654au_0_pon_pwrkey: pwrkey {
+				compatible = "qcom,pmm8654au-pwrkey", "qcom,pmk8350-pwrkey";
+				interrupts-extended = <&spmi_bus 0x0 0x12 0x7 IRQ_TYPE_EDGE_BOTH>;
+				linux,code = <KEY_POWER>;
+				debounce = <15625>;
+			};
+
+			pmm8654au_0_pon_resin: resin {
+				compatible = "qcom,pmm8654au-resin", "qcom,pmk8350-resin";
+				interrupts-extended = <&spmi_bus 0x0 0x12 0x6 IRQ_TYPE_EDGE_BOTH>;
+				linux,code = <KEY_VOLUMEDOWN>;
+				debounce = <15625>;
+			};
+		};
+
 		pmm8620au_0_rtc: rtc@6100 {
 			compatible = "qcom,pmk8350-rtc";
 			reg = <0x6100>, <0x6200>;

-- 
2.34.1


^ permalink raw reply related

* [PATCH] Input: change joystick 80 buttons limitation
From: Ricardo Esteves @ 2026-02-09 13:36 UTC (permalink / raw)
  To: linux-kernel; +Cc: linux-input, dmitry.torokhov, ricardo.lopes.esteves


[-- Attachment #1.1.1: Type: text/plain, Size: 1389 bytes --]

Currently linux joystick support is limited to 80 buttons.

The default value for the max scan code that a key/button can have in 
the linux kernel is 0x2ff (767), which is equivalent to 80 keys/buttons.

The value i propose in the bellow patch is 0x31d (797) which is +30 
buttons, so a max of 110 keys/buttons.

Works perfectly with WINWING Orion Throttle Base II + F15EX HANDLE, all 
110 buttons are recognized (is the joystick i found to have the biggest 
amount of buttons so far).


--- a/include/linux/mod_devicetable.h	2025-11-14 16:31:54.542228221 +0100
+++ a/include/linux/mod_devicetable.h	2025-11-02 01:00:00.000000000 +0100
@@ -333,7 +333,7 @@
  /* Input */
  #define INPUT_DEVICE_ID_EV_MAX		0x1f
  #define INPUT_DEVICE_ID_KEY_MIN_INTERESTING	0x71
-#define INPUT_DEVICE_ID_KEY_MAX		0x2ff
+#define INPUT_DEVICE_ID_KEY_MAX		0x31d
  #define INPUT_DEVICE_ID_REL_MAX		0x0f
  #define INPUT_DEVICE_ID_ABS_MAX		0x3f
  #define INPUT_DEVICE_ID_MSC_MAX		0x07
--- a/include/uapi/linux/input-event-codes.h	2025-11-02 
01:00:00.000000000 +0100
+++ a/include/uapi/linux/input-event-codes.h	2025-11-14 
16:34:37.218263985 +0100
@@ -817,7 +817,7 @@

  /* We avoid low common keys in module aliases so they don't get huge. */
  #define KEY_MIN_INTERESTING	KEY_MUTE
-#define KEY_MAX			0x2ff
+#define KEY_MAX			0x31d
  #define KEY_CNT			(KEY_MAX+1)

  /*



[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 3207 bytes --]

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]

^ permalink raw reply

* Re: [PATCH v3 1/3] dt-bindings: input: awinic,aw86927: Add Awinic AW86938
From: Krzysztof Kozlowski @ 2026-02-09 13:41 UTC (permalink / raw)
  To: Griffin Kroah-Hartman, Dmitry Torokhov, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
	Luca Weiss
  Cc: linux-input, devicetree, linux-kernel, linux-arm-msm
In-Reply-To: <20260209-aw86938-driver-v3-1-5c79cff30492@fairphone.com>

On 09/02/2026 13:59, Griffin Kroah-Hartman wrote:
> Add bindings for the Awinic AW86938 haptic chip which can be found in
> smartphones. These two chips require a similar devicetree configuration,
> but have a register layout that's not 100% compatible.

... however chip model is fully detectable via ID register.
(or something similar to justify usage of fallback compatible)

Anyway:
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH v2 1/3] dt-bindings: power: reset: qcom-pon: Add new compatible PMM8654AU
From: Krzysztof Kozlowski @ 2026-02-09 13:49 UTC (permalink / raw)
  To: Rakesh Kota, Sebastian Reichel, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Vinod Koul, Dmitry Torokhov, Courtney Cavin,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, linux-input
In-Reply-To: <20260209-add_pwrkey_and_resin-v2-1-f944d87b9a93@oss.qualcomm.com>

On 09/02/2026 14:23, Rakesh Kota wrote:
> Add the compatible string "qcom,pmm8654au-pon" for the PMM8654AU PMIC.
> The PON peripheral on PMM8654AU is compatible with PMK8350, so it is
> documented as a fallback to "qcom,pmk8350-pon".

Drop everything after ,. Do not explain WHAT you did. We see it.

> 
> While PMM8654AU supports additional registers compared to the baseline,

full stop.

> there is currently no active use case for these features. This specific
> compatible string reserves the identifier for future hardware-specific
> handling if required.

All the rest is irrelevant or even wrong. We do not reserve identifiers.
If you want to reserve something, then I need to reject the patch.

> 
> Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
> ---

Where is the changelog? Nothing in cover letter explained what was
happening with this patch, nothing is here.

>  .../devicetree/bindings/power/reset/qcom,pon.yaml        | 16 ++++++++++------
>  1 file changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/power/reset/qcom,pon.yaml b/Documentation/devicetree/bindings/power/reset/qcom,pon.yaml
> index 979a377cb4ffd577bfa51b9a3cd089acc202de0c..14b85b0d97da12c756cfe2ce33853501ba4ca46c 100644
> --- a/Documentation/devicetree/bindings/power/reset/qcom,pon.yaml
> +++ b/Documentation/devicetree/bindings/power/reset/qcom,pon.yaml
> @@ -17,12 +17,16 @@ description: |
>  
>  properties:
>    compatible:
> -    enum:
> -      - qcom,pm8916-pon
> -      - qcom,pm8941-pon
> -      - qcom,pms405-pon
> -      - qcom,pm8998-pon
> -      - qcom,pmk8350-pon
> +    oneOf:
> +      - enum:
> +          - qcom,pm8916-pon
> +          - qcom,pm8941-pon
> +          - qcom,pms405-pon
> +          - qcom,pm8998-pon

Move this one up to to fix sorting while at it.

> +          - qcom,pmk8350-pon

And this above pms.

> +      - items:
> +          - const: qcom,pmm8654au-pon
> +          - const: qcom,pmk8350-pon

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH v2 2/3] dt-bindings: input: qcom,pm8941-pwrkey: Document PMM8654AU
From: Krzysztof Kozlowski @ 2026-02-09 13:50 UTC (permalink / raw)
  To: Rakesh Kota, Sebastian Reichel, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Vinod Koul, Dmitry Torokhov, Courtney Cavin,
	Bjorn Andersson, Konrad Dybcio
  Cc: linux-pm, devicetree, linux-kernel, linux-arm-msm, linux-input
In-Reply-To: <20260209-add_pwrkey_and_resin-v2-2-f944d87b9a93@oss.qualcomm.com>

On 09/02/2026 14:23, Rakesh Kota wrote:
> Add compatible strings for PMM8654AU power key and resin support.
> These blocks are compatible with PMK8350, so use that as the
> fallback.
> 
> Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>

No changelog? Nothing in the cover letter explained what happened here.

Anyway, don't want to block on such trivialities:

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Best regards,
Krzysztof

^ permalink raw reply

* Re: [PATCH] usbhid: tolerate intermittent errors
From: Alan Stern @ 2026-02-09 14:47 UTC (permalink / raw)
  To: Oliver Neukum
  Cc: Liam Mitchell, Jiri Kosina, Benjamin Tissoires, linux-usb,
	linux-input, linux-kernel
In-Reply-To: <a31763aa-77af-4e13-8708-b007ed53277c@suse.com>

On Mon, Feb 09, 2026 at 11:06:03AM +0100, Oliver Neukum wrote:
> On 08.02.26 18:10, Liam Mitchell wrote:
> > Modifies the usbhid error handling logic to better handle intermittent
> > errors like EPROTO, which should only need resubmission of URBs and not
> > full device reset.
> > 
> > Reduces initial retry delay from 13ms to 1ms. The faster the URB is
> > resubmitted, the lower the chance that user events will be missed.
> 
> Hi,
> 
> in this case I have to ask the obvious question: Why wait at all?

Because of the possibility that the error was caused by transient 
interference that might not go away immediately.

> It would seem to me that if you have spurious or intermittent errors
> the right time to retry is immediately.

It depends on the cause of the errors.  In any case, a short delay, such 
as 1 ms, should not make much difference.

Alan Stern

^ permalink raw reply

* Re: [PATCH v3 2/3] Input: aw86938 - add driver for Awinic AW86938
From: Dmitry Torokhov @ 2026-02-09 14:59 UTC (permalink / raw)
  To: Griffin Kroah-Hartman
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
	Konrad Dybcio, Luca Weiss, linux-input, devicetree, linux-kernel,
	linux-arm-msm
In-Reply-To: <20260209-aw86938-driver-v3-2-5c79cff30492@fairphone.com>

Hi Griffin,

On Mon, Feb 09, 2026 at 01:59:46PM +0100, Griffin Kroah-Hartman wrote:
> @@ -377,7 +390,7 @@ static int aw86927_play_sine(struct aw86927_data *haptics)
>  		return err;
>  
>  	/* set gain to value lower than 0x80 to avoid distorted playback */
> -	err = regmap_write(haptics->regmap, AW86927_PLAYCFG2_REG, 0x7c);
> +	err = regmap_write(haptics->regmap, AW86927_PLAYCFG2_REG, 0x45);
>  	if (err)
>  		return err;
>  

Sorry, just noticed this: does this really belong to this patch or maybe
it needs be split?

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v5 1/1] Input: cros_ec_keyb - add function key support
From: Fabio Baltieri @ 2026-02-09 15:46 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Benson Leung, Guenter Roeck, Tzung-Bi Shih, Simon Glass,
	linux-input, chrome-platform, linux-kernel
In-Reply-To: <aYYTgxi0mcPVgpTr@google.com>

On Fri, Feb 06, 2026 at 08:25:14AM -0800, Dmitry Torokhov wrote:
> Hi Fabio,
> 
> On Mon, Jan 12, 2026 at 09:33:09AM +0000, Fabio Baltieri wrote:
> > Add support for handling an Fn button and sending separate keycodes for
> > a subset of keys in the matrix defined in the upper half of the keymap.
> > 
> > Signed-off-by: Fabio Baltieri <fabiobaltieri@chromium.org>
> > Reviewed-by: Simon Glass <sjg@chromium.org>
> > ---
> >  drivers/input/keyboard/cros_ec_keyb.c | 174 +++++++++++++++++++++++---
> >  1 file changed, 158 insertions(+), 16 deletions(-)
> > 
> > diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c
> > index 1c6b0461dc35..93540f0c5a33 100644
> > --- a/drivers/input/keyboard/cros_ec_keyb.c
> > +++ b/drivers/input/keyboard/cros_ec_keyb.c
> > @@ -29,6 +29,11 @@
> >  
> >  #include <linux/unaligned.h>
> >  
> > +/* Maximum size of the normal key matrix, this is limited by the host command
> > + * key_matrix field defined in ec_response_get_next_data_v3
> > + */
> 
> The comment format for multi-line comments is:
> 
> /*
>  * Line 1
>  * Line 2
>  */

Sure will fix it.

> 
> > +#define CROS_EC_KEYBOARD_COLS_MAX 18
> > +
> >  /**
> >   * struct cros_ec_keyb - Structure representing EC keyboard device
> >   *
> > @@ -44,6 +49,11 @@
> >   * @bs_idev: The input device for non-matrix buttons and switches (or NULL).
> >   * @notifier: interrupt event notifier for transport devices
> >   * @vdata: vivaldi function row data
> > + * @has_fn_map: whether the driver uses an fn function-map layer
> 
> I do not believe this flag is needed. Always do FN processing. If there
> is no FN in the keymap it should work just fine.

The problem is that if there is an Fn key and a keymap, hence we process
the Fn keys in the kernel, then we don't send the Fn events, but we
currently have devices deployed with an Fn key where the key is handled
by the userspace and they expect KEY_FN events to be emitted, so if I
let the "fn keymap" logic kick in it unconditionally it would cause a
regression for existing devices.

> 
> > + * @normal_key_status: active normal keys map
> > + * @fn_key_status: active function keys map
> 
> I do not think you need to track state yourself. A key will be reported
> either from FN part of map or from normal one, so when you get a release
> for (row, col) you can check if FN-mapped key is active (using
> text_bit(<fn-combo-code>, idev->key)) and if it is not active then send
> release event for the normal key.

Cool, yes that's the case, was able to get rid of both these two, thanks
for the pointer.

> 
> > + * @fn_key_pressed: tracks the function key status
> > + * @fn_key_triggered: tracks where any function key fired
> 
> Maybe it should be called fn_event_pending? You set it together with
> fn_key_pressed and clear if you get any other key press?

Sounds good I'll rename it.

> 
> >   */
> >  struct cros_ec_keyb {
> >  	unsigned int rows;
> > @@ -61,6 +71,12 @@ struct cros_ec_keyb {
> >  	struct notifier_block notifier;
> >  
> >  	struct vivaldi_data vdata;
> > +
> > +	bool has_fn_map;
> > +	u8 normal_key_status[CROS_EC_KEYBOARD_COLS_MAX];
> > +	u8 fn_key_status[CROS_EC_KEYBOARD_COLS_MAX];
> > +	bool fn_key_pressed;
> > +	bool fn_key_triggered;
> >  };
> >  
> >  /**
> > @@ -166,16 +182,104 @@ static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, uint8_t *buf)
> >  	return false;
> >  }
> >  
> > +/*
> > + * Process a function key state change, send an event report if appropriate.
> > + */
> > +static void cros_ec_keyb_process_fn_key(struct cros_ec_keyb *ckdev,
> > +					int row, int col, bool state)
> > +{
> > +	struct input_dev *idev = ckdev->idev;
> > +	int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
> > +
> > +	ckdev->fn_key_pressed = state;
> > +
> > +	if (state) {
> > +		ckdev->fn_key_triggered = false;
> > +	} else if (!ckdev->fn_key_triggered) {
> > +		/*
> > +		 * Send the original code if nothing else has been pressed
> > +		 * together with Fn.
> > +		 */
> > +		input_event(idev, EV_MSC, MSC_SCAN, pos);
> > +		input_report_key(idev, KEY_FN, true);
> > +		input_sync(idev);
> > +
> > +		input_event(idev, EV_MSC, MSC_SCAN, pos);
> > +		input_report_key(idev, KEY_FN, false);
> 
> Why do we want this? If you want FN to behave like hardware switch you
> probably do not want to send KEY_FN at all?

Yeah normally you wouldn't want FN events, the problem though is that if
you don't send any events at all then a user may find a blanked screen,
hit the Fn key expecting it to unblank and instead it doesn't happen and
they assume the device is dead. My laptop does that too (in fact it
sends a KEY_WAKEUP).

Also I guess this behavior ultimately allows the userspace to bind
actions to the both the Fn key and Fn key function (imagine an UI like
"press the key to bind this event", if you emit Fn then it woulc capture
that one, if you never emit anything you just can't use it).

> 
> > +	}
> > +}
> > +
> > +/*
> > + * Return the Fn code for a normal key row, col combination, optionally set a
> > + * position code too.
> > + */
> > +static unsigned int cros_ec_keyb_fn_code(struct cros_ec_keyb *ckdev,
> > +					 int row, int col, int *pos)
> > +{
> > +	struct input_dev *idev = ckdev->idev;
> > +	const unsigned short *keycodes = idev->keycode;
> > +	int fn_pos = MATRIX_SCAN_CODE(row + ckdev->rows, col, ckdev->row_shift);
> > +
> > +	if (pos)
> > +		*pos = fn_pos;
> > +
> > +	return keycodes[fn_pos];
> > +}
> > +
> > +/*
> > + * Process the new state for a single key.
> > + */
> > +static void cros_ec_keyb_process_one(struct cros_ec_keyb *ckdev,
> > +				     int row, int col, bool state)
> > +{
> > +	struct input_dev *idev = ckdev->idev;
> > +	const unsigned short *keycodes = idev->keycode;
> > +	int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
> > +	unsigned int code = keycodes[pos];
> > +
> > +	dev_dbg(ckdev->dev, "changed: [r%d c%d]: byte %02x\n", row, col, state);
> > +
> > +	if (ckdev->has_fn_map) {
> > +		if (code == KEY_FN)
> > +			return cros_ec_keyb_process_fn_key(ckdev, row, col, state);
> > +
> > +		if (!state) {
> > +			if (ckdev->fn_key_status[col] & BIT(row)) {
> > +				code = cros_ec_keyb_fn_code(ckdev, row, col, &pos);
> > +
> > +				ckdev->fn_key_status[col] &= ~BIT(row);
> > +			} else if (ckdev->normal_key_status[col] & BIT(row)) {
> > +				ckdev->normal_key_status[col] &= ~BIT(row);
> > +			} else {
> > +				/* Discard, key press code was not sent */
> > +				return;
> > +			}
> > +		} else if (ckdev->fn_key_pressed) {
> > +			code = cros_ec_keyb_fn_code(ckdev, row, col, &pos);
> > +
> > +			ckdev->fn_key_triggered = true;
> > +
> > +			if (!code)
> > +				return;
> > +
> > +			ckdev->fn_key_status[col] |= BIT(row);
> > +		} else {
> > +			ckdev->normal_key_status[col] |= BIT(row);
> > +		}
> > +	}
> > +
> > +	input_event(idev, EV_MSC, MSC_SCAN, pos);
> > +	input_report_key(idev, code, state);
> > +}
> >  
> >  /*
> >   * Compares the new keyboard state to the old one and produces key
> > - * press/release events accordingly.  The keyboard state is 13 bytes (one byte
> > - * per column)
> > + * press/release events accordingly.  The keyboard state is one byte
> > + * per column.
> >   */
> >  static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
> >  			 uint8_t *kb_state, int len)
> >  {
> > -	struct input_dev *idev = ckdev->idev;
> >  	int col, row;
> >  	int new_state;
> >  	int old_state;
> > @@ -192,20 +296,13 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
> >  
> >  	for (col = 0; col < ckdev->cols; col++) {
> >  		for (row = 0; row < ckdev->rows; row++) {
> > -			int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
> > -			const unsigned short *keycodes = idev->keycode;
> > -
> >  			new_state = kb_state[col] & (1 << row);
> >  			old_state = ckdev->old_kb_state[col] & (1 << row);
> > -			if (new_state != old_state) {
> > -				dev_dbg(ckdev->dev,
> > -					"changed: [r%d c%d]: byte %02x\n",
> > -					row, col, new_state);
> > -
> > -				input_event(idev, EV_MSC, MSC_SCAN, pos);
> > -				input_report_key(idev, keycodes[pos],
> > -						 new_state);
> > -			}
> > +
> > +			if (new_state == old_state)
> > +				continue;
> > +
> > +			cros_ec_keyb_process_one(ckdev, row, col, new_state);
> >  		}
> >  		ckdev->old_kb_state[col] = kb_state[col];
> >  	}
> > @@ -582,6 +679,43 @@ static void cros_ec_keyb_parse_vivaldi_physmap(struct cros_ec_keyb *ckdev)
> >  	ckdev->vdata.num_function_row_keys = n_physmap;
> >  }
> >  
> > +/* Returns true if there is a KEY_FN code defined in the normal keymap */
> > +static bool cros_ec_keyb_has_fn_key(struct cros_ec_keyb *ckdev)
> > +{
> > +	struct input_dev *idev = ckdev->idev;
> > +	const unsigned short *keycodes = idev->keycode;
> > +
> > +	for (int row = 0; row < ckdev->rows; row++) {
> > +		for (int col = 0; col < ckdev->cols; col++) {
> > +			int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
> > +
> > +			if (keycodes[pos] == KEY_FN)
> > +				return true;
> > +		}
> > +	}
> > +
> > +	return false;
> > +}
> 
> Not needed.
> 
> > +
> > +/*
> > + * Returns true if there is a KEY_FN defined and at least one key in the fn
> > + * layer keymap
> > + */
> > +static bool cros_ec_keyb_has_fn_map(struct cros_ec_keyb *ckdev)
> > +{
> > +	if (!cros_ec_keyb_has_fn_key(ckdev))
> > +		return false;
> > +
> > +	for (int row = 0; row < ckdev->rows; row++) {
> > +		for (int col = 0; col < ckdev->cols; col++) {
> > +			if (cros_ec_keyb_fn_code(ckdev, row, col, NULL) != 0)
> > +				return true;
> > +		}
> > +	}
> > +
> > +	return false;
> > +}
> 
> I do not think this is needed either.

See my comment about has_fn_map.

^ permalink raw reply

* [PATCH v6 0/1] Input: cros_ec_keyb - add function key support
From: Fabio Baltieri @ 2026-02-09 15:51 UTC (permalink / raw)
  To: Dmitry Torokhov, Benson Leung, Guenter Roeck
  Cc: Fabio Baltieri, Tzung-Bi Shih, Simon Glass, linux-input,
	chrome-platform, linux-kernel

Changes from v5:
  - minor renames/cosmetic changes
  - dropped the *_key_status array, tracking using the idev->key bitmask

Changes from v4:
  - just a comment tweak

Changes from v3:
  - implemented fn layer runtime detection
  - tweaked cros_ec_keyb_fn_code to return back the correct position
    code

Changes from v2:
  - renamed the dt property to use-fn-map, dropped the example
  - added few function comments
  - added a helper for obtaining the fn code
  - reordered, dt patch first

Changes from v1:
  - change struct to short types
  - refactored the fn key handling in its own function
  - changed props to use the google, prefix
  - reworked the properties to use an overlay map rather than a
    dedicated one

Fabio Baltieri (1):
  Input: cros_ec_keyb - add function key support

 drivers/input/keyboard/cros_ec_keyb.c | 167 +++++++++++++++++++++++---
 1 file changed, 151 insertions(+), 16 deletions(-)

-- 
2.53.0.rc2.204.g2597b5adb4-goog


^ permalink raw reply

* [PATCH v6 1/1] Input: cros_ec_keyb - add function key support
From: Fabio Baltieri @ 2026-02-09 15:51 UTC (permalink / raw)
  To: Dmitry Torokhov, Benson Leung, Guenter Roeck
  Cc: Fabio Baltieri, Tzung-Bi Shih, Simon Glass, linux-input,
	chrome-platform, linux-kernel
In-Reply-To: <20260209155127.158813-1-fabiobaltieri@chromium.org>

Add support for handling an Fn button and sending separate keycodes for
a subset of keys in the matrix defined in the upper half of the keymap.

Signed-off-by: Fabio Baltieri <fabiobaltieri@chromium.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
 drivers/input/keyboard/cros_ec_keyb.c | 167 +++++++++++++++++++++++---
 1 file changed, 151 insertions(+), 16 deletions(-)

diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c
index 1c6b0461dc35..cda56270cac8 100644
--- a/drivers/input/keyboard/cros_ec_keyb.c
+++ b/drivers/input/keyboard/cros_ec_keyb.c
@@ -29,6 +29,12 @@
 
 #include <linux/unaligned.h>
 
+/*
+ * Maximum size of the normal key matrix, this is limited by the host command
+ * key_matrix field defined in ec_response_get_next_data_v3
+ */
+#define CROS_EC_KEYBOARD_COLS_MAX 18
+
 /**
  * struct cros_ec_keyb - Structure representing EC keyboard device
  *
@@ -44,6 +50,9 @@
  * @bs_idev: The input device for non-matrix buttons and switches (or NULL).
  * @notifier: interrupt event notifier for transport devices
  * @vdata: vivaldi function row data
+ * @has_fn_map: whether the driver uses an fn function-map layer
+ * @fn_key_pressed: tracks the function key status
+ * @fn_event_pending: tracks where any function key fired
  */
 struct cros_ec_keyb {
 	unsigned int rows;
@@ -61,6 +70,10 @@ struct cros_ec_keyb {
 	struct notifier_block notifier;
 
 	struct vivaldi_data vdata;
+
+	bool has_fn_map;
+	bool fn_key_pressed;
+	bool fn_event_pending;
 };
 
 /**
@@ -166,16 +179,100 @@ static bool cros_ec_keyb_has_ghosting(struct cros_ec_keyb *ckdev, uint8_t *buf)
 	return false;
 }
 
+/*
+ * Process a function key state change, send an event report if appropriate.
+ */
+static void cros_ec_keyb_process_fn_key(struct cros_ec_keyb *ckdev,
+					int row, int col, bool state)
+{
+	struct input_dev *idev = ckdev->idev;
+	int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
+
+	ckdev->fn_key_pressed = state;
+
+	if (state) {
+		ckdev->fn_event_pending = false;
+	} else if (!ckdev->fn_event_pending) {
+		/*
+		 * Send the original code if nothing else has been pressed
+		 * together with Fn.
+		 */
+		input_event(idev, EV_MSC, MSC_SCAN, pos);
+		input_report_key(idev, KEY_FN, true);
+		input_sync(idev);
+
+		input_event(idev, EV_MSC, MSC_SCAN, pos);
+		input_report_key(idev, KEY_FN, false);
+	}
+}
+
+/*
+ * Return the Fn code for a normal key row, col combination, optionally set a
+ * position code too.
+ */
+static unsigned int cros_ec_keyb_fn_code(struct cros_ec_keyb *ckdev,
+					 int row, int col, int *pos)
+{
+	struct input_dev *idev = ckdev->idev;
+	const unsigned short *keycodes = idev->keycode;
+	int fn_pos = MATRIX_SCAN_CODE(row + ckdev->rows, col, ckdev->row_shift);
+
+	if (pos)
+		*pos = fn_pos;
+
+	return keycodes[fn_pos];
+}
+
+/*
+ * Process the new state for a single key.
+ */
+static void cros_ec_keyb_process_one(struct cros_ec_keyb *ckdev,
+				     int row, int col, bool state)
+{
+	struct input_dev *idev = ckdev->idev;
+	const unsigned short *keycodes = idev->keycode;
+	int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
+	unsigned int code = keycodes[pos];
+
+	dev_dbg(ckdev->dev, "changed: [r%d c%d]: byte %02x\n", row, col, state);
+
+	if (ckdev->has_fn_map) {
+		unsigned int fn_code = cros_ec_keyb_fn_code(ckdev, row, col, &pos);
+
+		if (code == KEY_FN)
+			return cros_ec_keyb_process_fn_key(ckdev, row, col, state);
+
+		if (!state) {
+			if (test_bit(fn_code, idev->key)) {
+				code = fn_code;
+			} else if (test_bit(code, idev->key)) {
+				/* nothing to do */
+			} else {
+				/* Discard, key press code was not sent */
+				return;
+			}
+		} else if (ckdev->fn_key_pressed) {
+			ckdev->fn_event_pending = true;
+
+			if (!fn_code)
+				return;
+
+			code = fn_code;
+		}
+	}
+
+	input_event(idev, EV_MSC, MSC_SCAN, pos);
+	input_report_key(idev, code, state);
+}
 
 /*
  * Compares the new keyboard state to the old one and produces key
- * press/release events accordingly.  The keyboard state is 13 bytes (one byte
- * per column)
+ * press/release events accordingly.  The keyboard state is one byte
+ * per column.
  */
 static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
 			 uint8_t *kb_state, int len)
 {
-	struct input_dev *idev = ckdev->idev;
 	int col, row;
 	int new_state;
 	int old_state;
@@ -192,20 +289,13 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
 
 	for (col = 0; col < ckdev->cols; col++) {
 		for (row = 0; row < ckdev->rows; row++) {
-			int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
-			const unsigned short *keycodes = idev->keycode;
-
 			new_state = kb_state[col] & (1 << row);
 			old_state = ckdev->old_kb_state[col] & (1 << row);
-			if (new_state != old_state) {
-				dev_dbg(ckdev->dev,
-					"changed: [r%d c%d]: byte %02x\n",
-					row, col, new_state);
-
-				input_event(idev, EV_MSC, MSC_SCAN, pos);
-				input_report_key(idev, keycodes[pos],
-						 new_state);
-			}
+
+			if (new_state == old_state)
+				continue;
+
+			cros_ec_keyb_process_one(ckdev, row, col, new_state);
 		}
 		ckdev->old_kb_state[col] = kb_state[col];
 	}
@@ -582,6 +672,43 @@ static void cros_ec_keyb_parse_vivaldi_physmap(struct cros_ec_keyb *ckdev)
 	ckdev->vdata.num_function_row_keys = n_physmap;
 }
 
+/* Returns true if there is a KEY_FN code defined in the normal keymap */
+static bool cros_ec_keyb_has_fn_key(struct cros_ec_keyb *ckdev)
+{
+	struct input_dev *idev = ckdev->idev;
+	const unsigned short *keycodes = idev->keycode;
+
+	for (int row = 0; row < ckdev->rows; row++) {
+		for (int col = 0; col < ckdev->cols; col++) {
+			int pos = MATRIX_SCAN_CODE(row, col, ckdev->row_shift);
+
+			if (keycodes[pos] == KEY_FN)
+				return true;
+		}
+	}
+
+	return false;
+}
+
+/*
+ * Returns true if there is a KEY_FN defined and at least one key in the fn
+ * layer keymap
+ */
+static bool cros_ec_keyb_has_fn_map(struct cros_ec_keyb *ckdev)
+{
+	if (!cros_ec_keyb_has_fn_key(ckdev))
+		return false;
+
+	for (int row = 0; row < ckdev->rows; row++) {
+		for (int col = 0; col < ckdev->cols; col++) {
+			if (cros_ec_keyb_fn_code(ckdev, row, col, NULL) != 0)
+				return true;
+		}
+	}
+
+	return false;
+}
+
 /**
  * cros_ec_keyb_register_matrix - Register matrix keys
  *
@@ -603,6 +730,12 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
 	if (err)
 		return err;
 
+	if (ckdev->cols > CROS_EC_KEYBOARD_COLS_MAX) {
+		dev_err(dev, "keypad,num-columns too large: %d (max: %d)\n",
+			ckdev->cols, CROS_EC_KEYBOARD_COLS_MAX);
+		return -EINVAL;
+	}
+
 	ckdev->valid_keys = devm_kzalloc(dev, ckdev->cols, GFP_KERNEL);
 	if (!ckdev->valid_keys)
 		return -ENOMEM;
@@ -635,7 +768,7 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
 	ckdev->ghost_filter = device_property_read_bool(dev,
 					"google,needs-ghost-filter");
 
-	err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols,
+	err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows * 2, ckdev->cols,
 					 NULL, idev);
 	if (err) {
 		dev_err(dev, "cannot build key matrix\n");
@@ -650,6 +783,8 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
 	cros_ec_keyb_compute_valid_keys(ckdev);
 	cros_ec_keyb_parse_vivaldi_physmap(ckdev);
 
+	ckdev->has_fn_map = cros_ec_keyb_has_fn_map(ckdev);
+
 	err = input_register_device(ckdev->idev);
 	if (err) {
 		dev_err(dev, "cannot register input device\n");
-- 
2.53.0.rc2.204.g2597b5adb4-goog


^ permalink raw reply related

* Re: [PATCH v5 1/1] Input: cros_ec_keyb - add function key support
From: Dmitry Torokhov @ 2026-02-09 18:20 UTC (permalink / raw)
  To: Fabio Baltieri
  Cc: Benson Leung, Guenter Roeck, Tzung-Bi Shih, Simon Glass,
	linux-input, chrome-platform, linux-kernel
In-Reply-To: <aYoBTEgrirtcW96F@google.com>

On Mon, Feb 09, 2026 at 03:46:20PM +0000, Fabio Baltieri wrote:
> On Fri, Feb 06, 2026 at 08:25:14AM -0800, Dmitry Torokhov wrote:
> > 
> > I do not believe this flag is needed. Always do FN processing. If there
> > is no FN in the keymap it should work just fine.
> 
> The problem is that if there is an Fn key and a keymap, hence we process
> the Fn keys in the kernel, then we don't send the Fn events, but we
> currently have devices deployed with an Fn key where the key is handled
> by the userspace and they expect KEY_FN events to be emitted, so if I
> let the "fn keymap" logic kick in it unconditionally it would cause a
> regression for existing devices.

Hmm, I see. Then I think we really need to have it as a device property,
because keymap can be manipulated at runtime, so depending on it to
switch processing seems weird.

It is like autorepeat, either device configuration asks for it, or it
does not...

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v5 1/1] Input: cros_ec_keyb - add function key support
From: Fabio Baltieri @ 2026-02-09 19:33 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Benson Leung, Guenter Roeck, Tzung-Bi Shih, Simon Glass,
	linux-input, chrome-platform, linux-kernel
In-Reply-To: <aYoZEztHrIx5CzwQ@google.com>

On Mon, Feb 09, 2026 at 10:20:52AM -0800, Dmitry Torokhov wrote:
> On Mon, Feb 09, 2026 at 03:46:20PM +0000, Fabio Baltieri wrote:
> > On Fri, Feb 06, 2026 at 08:25:14AM -0800, Dmitry Torokhov wrote:
> > > 
> > > I do not believe this flag is needed. Always do FN processing. If there
> > > is no FN in the keymap it should work just fine.
> > 
> > The problem is that if there is an Fn key and a keymap, hence we process
> > the Fn keys in the kernel, then we don't send the Fn events, but we
> > currently have devices deployed with an Fn key where the key is handled
> > by the userspace and they expect KEY_FN events to be emitted, so if I
> > let the "fn keymap" logic kick in it unconditionally it would cause a
> > regression for existing devices.
> 
> Hmm, I see. Then I think we really need to have it as a device property,
> because keymap can be manipulated at runtime, so depending on it to
> switch processing seems weird.
> 
> It is like autorepeat, either device configuration asks for it, or it
> does not...

Ok, the DT folks were fairly explicit about not wanting anything that
even remotely looks like configuration into dt. Right now the behavior
changes based on what's in the keymap, which I think is fine.

I see the keymap can be manipulated in runtime but then I guess I could
just install a custom hook to idev->setkeycode, recompute
cros_ec_keyb_has_fn_map() and then call input_default_getkeycode()?
I'd have to make that function public but then it'd automatically change
the behavior in runtime as keycodes are defined/undefined.

Would that be acceptable?

^ permalink raw reply

* Re: [PATCH v5 1/1] Input: cros_ec_keyb - add function key support
From: Dmitry Torokhov @ 2026-02-09 19:53 UTC (permalink / raw)
  To: Fabio Baltieri
  Cc: Benson Leung, Guenter Roeck, Tzung-Bi Shih, Simon Glass,
	linux-input, chrome-platform, linux-kernel
In-Reply-To: <aYo2cYhd-XCcLa43@google.com>

On Mon, Feb 09, 2026 at 07:33:05PM +0000, Fabio Baltieri wrote:
> On Mon, Feb 09, 2026 at 10:20:52AM -0800, Dmitry Torokhov wrote:
> > On Mon, Feb 09, 2026 at 03:46:20PM +0000, Fabio Baltieri wrote:
> > > On Fri, Feb 06, 2026 at 08:25:14AM -0800, Dmitry Torokhov wrote:
> > > > 
> > > > I do not believe this flag is needed. Always do FN processing. If there
> > > > is no FN in the keymap it should work just fine.
> > > 
> > > The problem is that if there is an Fn key and a keymap, hence we process
> > > the Fn keys in the kernel, then we don't send the Fn events, but we
> > > currently have devices deployed with an Fn key where the key is handled
> > > by the userspace and they expect KEY_FN events to be emitted, so if I
> > > let the "fn keymap" logic kick in it unconditionally it would cause a
> > > regression for existing devices.
> > 
> > Hmm, I see. Then I think we really need to have it as a device property,
> > because keymap can be manipulated at runtime, so depending on it to
> > switch processing seems weird.
> > 
> > It is like autorepeat, either device configuration asks for it, or it
> > does not...
> 
> Ok, the DT folks were fairly explicit about not wanting anything that
> even remotely looks like configuration into dt. Right now the behavior
> changes based on what's in the keymap, which I think is fine.
> 
> I see the keymap can be manipulated in runtime but then I guess I could
> just install a custom hook to idev->setkeycode, recompute
> cros_ec_keyb_has_fn_map() and then call input_default_getkeycode()?
> I'd have to make that function public but then it'd automatically change
> the behavior in runtime as keycodes are defined/undefined.
> 
> Would that be acceptable?

OK, let's see how it will look like. Exporting
input_default_setkeycode() should be fine, we just need to stick
lockdep_assert_held() there to make sure it is not called without event
lock being held.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH] Input: change joystick 80 buttons limitation
From: Ivan Gorinov @ 2026-02-09 20:08 UTC (permalink / raw)
  To: Ricardo Esteves; +Cc: linux-kernel, linux-input, dmitry.torokhov
In-Reply-To: <fc66f27b-9a73-4a71-8dbe-f48609719d90@oracle.com>

On 2026-02-09 05:36, Ricardo Esteves wrote:

> Currently linux joystick support is limited to 80 buttons.
> The default value for the max scan code that a key/button can hav
e in the linux kernel is 0x2ff (767), which is equivalent to 80 
keys/buttons.
> The value i propose in the bellow patch is 0x31d (797) which is +30 
> buttons, so a max of 110 keys/buttons.
> Works perfectly with WINWING Orion Throttle Base II + F15EX HANDLE, all 
> 110 buttons are recognized (is the joystick i found to have the biggest 
> amount of buttons so far).

That device will be supported in 6.19, including LED controls. I have 
also posted a patch to enable rumble feedback.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/hid/hid-winwing.c?h=v6.19

^ permalink raw reply

* Re: [PATCH v1] input: xpad: Add support for BETOP BTP-KP50B/C, controller's wireless mode
From: liushuyu @ 2026-02-10  5:53 UTC (permalink / raw)
  To: Antheas Kapenekakis
  Cc: Shengyu Qu, dmitry.torokhov, vi, niltonperimneto, linux-input,
	linux-kernel
In-Reply-To: <CAGwozwFXmye4kJzjFbZzUmgmhHn0YyX2eEwidkUJBs7ZhpXhNw@mail.gmail.com>

Hi there,
> Hi,
> if I recall, this logic abuses some HID descriptor logic to cycle the
> mode depending on the OS. The arch wiki has a potential fix for
> certain controllers.
>
> This makes you end up in Android mode since linux kernel. Nintendo
> uses a BSD-based kernel, and the Windows NT kernel is different. So by
> breaking the protocol in different ways they get it to cycle.
>
> Antheas

I sent a patch to the linux-input list a few months ago to work around
this issue with the BETOP/Beitong controllers:
https://lore.kernel.org/linux-input/20260102030154.197749-3-liushuyu@aosc.io/.
It would be appreciated if anyone in the thread could verify if my
previous workaround works for their BETOP/Beitong controllers as well.

Thanks,
Zixing


^ permalink raw reply

* Re: [PATCH v2 2/3] dt-bindings: input: qcom,pm8941-pwrkey: Document PMM8654AU
From: Dmitry Torokhov @ 2026-02-10  6:20 UTC (permalink / raw)
  To: Rakesh Kota
  Cc: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Vinod Koul, Courtney Cavin, Bjorn Andersson, Konrad Dybcio,
	linux-pm, devicetree, linux-kernel, linux-arm-msm, linux-input
In-Reply-To: <20260209-add_pwrkey_and_resin-v2-2-f944d87b9a93@oss.qualcomm.com>

On Mon, Feb 09, 2026 at 06:53:37PM +0530, Rakesh Kota wrote:
> Add compatible strings for PMM8654AU power key and resin support.
> These blocks are compatible with PMK8350, so use that as the
> fallback.
> 
> Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>

Applied, thank you.

-- 
Dmitry

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox