From nobody Tue Apr 7 14:30:26 2026 Received: from mail-dl1-f50.google.com (mail-dl1-f50.google.com [74.125.82.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 29A853783C9 for ; Tue, 7 Apr 2026 04:14:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775535242; cv=none; b=jzBdkexjjyzVLnihLnFkRJtP2+F9ocPWzsjLoadqHAT/hh/u+WA/IMSZbX3g+4zKZtjtjnvJrCzfw0v2puzYWiTLdJ+B8hW0GH3UYGmK2EoH3kdDHzHp2s6pussF8uk13o/7LpWG3KpuP79o/DVHBMnMosk/MbAH4B3dRbUE6fU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775535242; c=relaxed/simple; bh=pH1X0aQzXpB3SyOTJrmNhcXASyFLtui/zFbVD/xGlF0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BAsQgAlDvFCoAuk7LifClwHtuW5n1tZpiGozIswy5KVByUZaFidyF/QZtENwdAVRMo8Q0iNGyN/7eFND2HbchaelTdwju7cFPSpnoJn/JZN+NC8TB0CO397MOn1owSWyiWTnoRVHIuhWm0XjpjCC+Oliw1NTYfAuOJjDEvpUKSc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Of/NfMa8; arc=none smtp.client-ip=74.125.82.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Of/NfMa8" Received: by mail-dl1-f50.google.com with SMTP id a92af1059eb24-1279eced0b9so5286421c88.0 for ; Mon, 06 Apr 2026 21:14:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775535239; x=1776140039; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ejgiW/r7pVVUy8vt9xK36NMd3PA7PnFF5ux4KM88uHM=; b=Of/NfMa8lSvWoS/flPyC6WLzjsNffRU/gbzsWCQxto3BO1PdeyqP0+mUu73QyeAaFM uao/gDLxEls/zgDEZBqdC70YAxwtdMkU+MKehADsn8MqyJTqzA7+LDOG/rTRzrzTHkbf NtqC6t2zZN/8JtoE3l2DuWt/q9hih5O0JPUYCDEHrTBjW7FI5BCQL8vtyPWimeq0x1Nn JwPCMK57yrBWIUUasvKCDkMvzwWJVBqGTY1+d1HQsJG/Lyjb2xEA07m71P9kzxtUdx8f W3NJWL/KBo4OMGILFbrI5ELEmDKf9TbgWBfTAxyWvphsBblcUiyc6jzYhukhqdJ7RM5/ cagg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775535239; x=1776140039; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ejgiW/r7pVVUy8vt9xK36NMd3PA7PnFF5ux4KM88uHM=; b=J4z/+NwCmsVgPJMYC4YO9aki1Az4caOsN9eqrS8D1sdS9IOuj83fVjUjDQToX2c94A orJSE2TlesSuKjzd/7EZmTy7eP7vvoomSG78fc13gzlPi9TnKP8uHPUkrK0R1kZeDRRL sDjKtj4VDmu3tEFEz2jPSvutZtsLmEUpdigqKLleNPQgxtPyOxrz8ikX2u0FS8xkNYi3 X3qqCAFFoKIpUY7YR0wWRL7/5W7YP8NqWLWZt6P8G2XqpL2j+Y2aWH907HfT0DDPU3Ab Czb/aHKOWJqV5T07xdFb+Gwm9VeZnv59uNAuCiy9FiXMRYsyOLd1r+vg4HOCXMmmyzjz dL8Q== X-Forwarded-Encrypted: i=1; AJvYcCXQyzVmKKpT7YLHwVCanpmRMIZKgVxTpXzgECRY109ll4TCDJrBgfFSL4tkNYlmqNk2xBD7MkiD1AguAZc=@vger.kernel.org X-Gm-Message-State: AOJu0YzI9kHfL+wOpiYiwWqmUWzaXBVZcA3Pv3amYjmJTJI+X0SVVWQ1 goUcqofqOrfsZvMFei2Y8YUH7Bctz8nHW2FcFX7zeVXBJ38DxQ6OGI8G X-Gm-Gg: AeBDievh/NiR37igJq/JN/78rXNseaXFn7loEhscBnavnfqVNnHos6KPLkGs/LiCXZH XJM/omaFsNA4oZ4bdvuku7alvn9dlCazoI8z22q2dfl59BoQTeAT7w5IRp0aka0r6N+uIynZldj 0XwrdPjZmqJGmgIU1Bki6lSh6A3Fbrkwu/RY1djombdV4UMLEwDv4DMnXofgYZfJZzMX71iZHrZ iI+xCc3g4yPmgOkUycQHO74soMeeNEI2CxrLnjAFI4guOgmH5e7DWboILRCjfNvL1A2iMUe2D2O 9iEyOu3Wnm45IZ+duaq80IhFuuFcAmMSqaamYHdRFP0kn1FztgBWy57VSHzpox/7jv3J/0QIAEZ 73ebLHq44zgU2ne9wFK4IsXKML90V6YHN6fn3TXCGC6NBgpejSyp6dtt1fV5lefC9W0Pzd+t9vb 50+niz0r0b4ZQSmUPb0TWxagIimvqLscDR/zh9OcZz49D3GEj5Uen9Eyjy/TPsVX1rvDoxskVf7 ak3 X-Received: by 2002:a05:7022:e09:b0:11a:342e:8a98 with SMTP id a92af1059eb24-12bfb63267fmr7475760c88.0.1775535239212; Mon, 06 Apr 2026 21:13:59 -0700 (PDT) Received: from lappy (108-228-232-20.lightspeed.sndgca.sbcglobal.net. [108.228.232.20]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-12bed93f861sm18523808c88.0.2026.04.06.21.13.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Apr 2026 21:13:58 -0700 (PDT) From: "Derek J. Clark" To: Jiri Kosina , Benjamin Tissoires Cc: "Pierre-Loup A . Griffais" , Lambert Fan , "Derek J . Clark" , linux-input@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/5] HID: hid-oxp: Add Second Generation Gamepad Mode Switch Date: Tue, 7 Apr 2026 04:13:52 +0000 Message-ID: <20260407041354.2283201-4-derekjohn.clark@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260407041354.2283201-1-derekjohn.clark@gmail.com> References: <20260407041354.2283201-1-derekjohn.clark@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Adds "gamepad_mode" attribute to second generation OneXPlayer configuration HID devices. This attribute initiates a mode shift in the device MCU that puts it into a state where all events are routed to an hidraw interface instead of the xpad evdev interface. This allows for debugging the hardware input mapping added in the next patch. Signed-off-by: Derek J. Clark --- v2: - Rename to gamepad_mode & show relevant gamepad modes instead of using a debug enable/disable paradigm, to match other drivers. --- drivers/hid/hid-oxp.c | 130 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/drivers/hid/hid-oxp.c b/drivers/hid/hid-oxp.c index 25214356163e..c62952537d98 100644 --- a/drivers/hid/hid-oxp.c +++ b/drivers/hid/hid-oxp.c @@ -33,6 +33,7 @@ enum oxp_function_index { OXP_FID_GEN1_RGB_SET =3D 0x07, OXP_FID_GEN1_RGB_REPLY =3D 0x0f, + OXP_FID_GEN2_TOGGLE_MODE =3D 0xb2, OXP_FID_GEN2_STATUS_EVENT =3D 0xb8, }; =20 @@ -41,11 +42,22 @@ static struct oxp_hid_cfg { struct hid_device *hdev; struct mutex cfg_mutex; /*ensure single synchronous output report*/ u8 rgb_brightness; + u8 gamepad_mode; u8 rgb_effect; u8 rgb_speed; u8 rgb_en; } drvdata; =20 +enum oxp_gamepad_mode_index { + OXP_GP_MODE_XINPUT =3D 0x00, + OXP_GP_MODE_DEBUG =3D 0x03, +}; + +static const char *const oxp_gamepad_mode_text[] =3D { + [OXP_GP_MODE_XINPUT] =3D "xinput", + [OXP_GP_MODE_DEBUG] =3D "debug", +}; + enum oxp_feature_en_index { OXP_FEAT_DISABLED, OXP_FEAT_ENABLED, @@ -181,6 +193,32 @@ static int oxp_hid_raw_event_gen_1(struct hid_device *= hdev, return 0; } =20 +static int oxp_gen_2_property_out(enum oxp_function_index fid, u8 *data, u= 8 data_size); + +static void oxp_mcu_init_fn(struct work_struct *work) +{ + u8 gp_mode_data[3] =3D { OXP_GP_MODE_DEBUG, 0x01, 0x02 }; + int ret; + + /* Cycle the gamepad mode */ + ret =3D oxp_gen_2_property_out(OXP_FID_GEN2_TOGGLE_MODE, gp_mode_data, 3); + if (ret) + dev_err(&drvdata.hdev->dev, + "Error: Failed to set gamepad mode: %i\n", ret); + + /* Remainder only applies for xinput mode */ + if (drvdata.gamepad_mode =3D=3D OXP_GP_MODE_DEBUG) + return; + + gp_mode_data[0] =3D OXP_GP_MODE_XINPUT; + ret =3D oxp_gen_2_property_out(OXP_FID_GEN2_TOGGLE_MODE, gp_mode_data, 3); + if (ret) + dev_err(&drvdata.hdev->dev, + "Error: Failed to set gamepad mode: %i\n", ret); +} + +static DECLARE_DELAYED_WORK(oxp_mcu_init, oxp_mcu_init_fn); + static int oxp_hid_raw_event_gen_2(struct hid_device *hdev, struct hid_report *report, u8 *data, int size) @@ -191,6 +229,14 @@ static int oxp_hid_raw_event_gen_2(struct hid_device *= hdev, if (data[0] !=3D OXP_FID_GEN2_STATUS_EVENT) return 0; =20 + /* Sent ~6s after resume event, indicating the MCU has fully reset. + * Re-apply our settings after this has been received. + */ + if (data[3] =3D=3D OXP_EFFECT_MONO_TRUE) { + mod_delayed_work(system_wq, &oxp_mcu_init, msecs_to_jiffies(50)); + return 0; + } + if (data[3] !=3D OXP_GET_PROPERTY) return 0; =20 @@ -288,6 +334,77 @@ static int oxp_gen_2_property_out(enum oxp_function_in= dex fid, u8 *data, footer_size); } =20 +static ssize_t gamepad_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + u16 up =3D get_usage_page(drvdata.hdev); + u8 data[3] =3D { 0x00, 0x01, 0x02 }; + int ret =3D -EINVAL; + int i; + + if (up !=3D GEN2_USAGE_PAGE) + return ret; + + for (i =3D 0; i < ARRAY_SIZE(oxp_gamepad_mode_text); i++) { + if (oxp_gamepad_mode_text[i] && sysfs_streq(buf, oxp_gamepad_mode_text[i= ])) { + ret =3D i; + break; + } + } + if (ret < 0) + return ret; + + data[0] =3D ret; + + ret =3D oxp_gen_2_property_out(OXP_FID_GEN2_TOGGLE_MODE, data, 3); + if (ret) + return ret; + + drvdata.gamepad_mode =3D data[0]; + + return count; +} + +static ssize_t gamepad_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%s\n", oxp_gamepad_mode_text[drvdata.gamepad_mode= ]); +} +static DEVICE_ATTR_RW(gamepad_mode); + +static ssize_t gamepad_mode_index_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + ssize_t count =3D 0; + unsigned int i; + + for (i =3D 0; i < ARRAY_SIZE(oxp_gamepad_mode_text); i++) { + if (!oxp_gamepad_mode_text[i] || + oxp_gamepad_mode_text[i][0] =3D=3D '\0') + continue; + + count +=3D sysfs_emit_at(buf, count, "%s ", oxp_gamepad_mode_text[i]); + } + + if (count) + buf[count - 1] =3D '\n'; + + return count; +} +static DEVICE_ATTR_RO(gamepad_mode_index); + +static struct attribute *oxp_cfg_attrs[] =3D { + &dev_attr_gamepad_mode.attr, + &dev_attr_gamepad_mode_index.attr, + NULL, +}; + +static const struct attribute_group oxp_cfg_attrs_group =3D { + .attrs =3D oxp_cfg_attrs, +}; + static int oxp_rgb_status_store(u8 enabled, u8 speed, u8 brightness) { u16 up =3D get_usage_page(drvdata.hdev); @@ -733,7 +850,20 @@ static int oxp_cfg_probe(struct hid_device *hdev, u16 = up) dev_warn(drvdata.led_mc->led_cdev.dev, "Failed to query RGB initial state: %i\n", ret); =20 + /* Below features are only implemented in gen 2 */ + if (up !=3D GEN2_USAGE_PAGE) + return 0; + skip_rgb: + mod_delayed_work(system_wq, &oxp_mcu_init, msecs_to_jiffies(50)); + + drvdata.gamepad_mode =3D OXP_GP_MODE_XINPUT; + + ret =3D devm_device_add_group(&hdev->dev, &oxp_cfg_attrs_group); + if (ret) + return dev_err_probe(&hdev->dev, ret, + "Failed to attach configuration attributes\n"); + return 0; } =20 --=20 2.53.0