public inbox for linux-input@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH RESEND] HID: winwing: Enable rumble effects
@ 2026-02-11  5:31 Ivan Gorinov
  2026-02-12  5:31 ` Dan Carpenter
  0 siblings, 1 reply; 2+ messages in thread
From: Ivan Gorinov @ 2026-02-11  5:31 UTC (permalink / raw)
  To: Jiri Kosina; +Cc: linux-input, linux-kernel

Enable rumble motor control on TGRIP-15E and TGRIP-15EX throttle grips
by sending haptic feedback commands (EV_FF events) to the input device.

Signed-off-by: Ivan Gorinov <linux-kernel@altimeter.info>
---
 drivers/hid/hid-winwing.c | 193 +++++++++++++++++++++++++++++++++++---
 1 file changed, 179 insertions(+), 14 deletions(-)

diff --git a/drivers/hid/hid-winwing.c b/drivers/hid/hid-winwing.c
index ab65dc12d1e0..031590ffd383 100644
--- a/drivers/hid/hid-winwing.c
+++ b/drivers/hid/hid-winwing.c
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/workqueue.h>
 
 #define MAX_REPORT 16
 
@@ -35,10 +36,14 @@ static const struct winwing_led_info led_info[3] = {
 
 struct winwing_drv_data {
 	struct hid_device *hdev;
-	__u8 *report_buf;
-	struct mutex lock;
-	int map_more_buttons;
-	unsigned int num_leds;
+	struct mutex lights_lock;
+	__u8 *report_lights;
+	__u8 *report_rumble;
+	struct work_struct rumble_work;
+	struct ff_rumble_effect rumble;
+	int rumble_left;
+	int rumble_right;
+	int has_grip15;
 	struct winwing_led leds[];
 };
 
@@ -47,10 +52,10 @@ static int winwing_led_write(struct led_classdev *cdev,
 {
 	struct winwing_led *led = (struct winwing_led *) cdev;
 	struct winwing_drv_data *data = hid_get_drvdata(led->hdev);
-	__u8 *buf = data->report_buf;
+	__u8 *buf = data->report_lights;
 	int ret;
 
-	mutex_lock(&data->lock);
+	mutex_lock(&data->lights_lock);
 
 	buf[0] = 0x02;
 	buf[1] = 0x60;
@@ -69,7 +74,7 @@ static int winwing_led_write(struct led_classdev *cdev,
 
 	ret = hid_hw_output_report(led->hdev, buf, 14);
 
-	mutex_unlock(&data->lock);
+	mutex_unlock(&data->lights_lock);
 
 	return ret;
 }
@@ -87,9 +92,9 @@ static int winwing_init_led(struct hid_device *hdev,
 	if (!data)
 		return -EINVAL;
 
-	data->report_buf = devm_kmalloc(&hdev->dev, MAX_REPORT, GFP_KERNEL);
+	data->report_lights = devm_kzalloc(&hdev->dev, MAX_REPORT, GFP_KERNEL);
 
-	if (!data->report_buf)
+	if (!data->report_lights)
 		return -ENOMEM;
 
 	for (i = 0; i < 3; i += 1) {
@@ -117,7 +122,7 @@ static int winwing_init_led(struct hid_device *hdev,
 	return ret;
 }
 
-static int winwing_map_button(int button, int map_more_buttons)
+static int winwing_map_button(int button, int has_grip15)
 {
 	if (button < 1)
 		return KEY_RESERVED;
@@ -141,7 +146,7 @@ static int winwing_map_button(int button, int map_more_buttons)
 		return (button - 65) + BTN_TRIGGER_HAPPY17;
 	}
 
-	if (!map_more_buttons) {
+	if (!has_grip15) {
 		/*
 		 * Not mapping numbers [33 .. 64] which
 		 * are not assigned to any real buttons
@@ -194,13 +199,150 @@ static int winwing_input_mapping(struct hid_device *hdev,
 	/* Button numbers start with 1 */
 	button = usage->hid & HID_USAGE;
 
-	code = winwing_map_button(button, data->map_more_buttons);
+	code = winwing_map_button(button, data->has_grip15);
 
 	hid_map_usage(hi, usage, bit, max, EV_KEY, code);
 
 	return 1;
 }
 
+/*
+ * If x ≤ 0, return 0;
+ * if x is in [1 .. 65535], return a value in [1 .. 255]
+ */
+static inline int convert_magnitude(int x)
+{
+	if (x < 1)
+		return 0;
+
+	return ((x * 255) >> 16) + 1;
+}
+
+static int winwing_haptic_rumble(struct winwing_drv_data *data)
+{
+	__u8 *buf;
+	__u8 m;
+
+	if (!data)
+		return -EINVAL;
+
+	buf = data->report_rumble;
+
+	if (!buf)
+		return -EINVAL;
+
+	if (!data->hdev) {
+		hid_err(data->hdev, "data->hdev == NULL\n");
+		return -EINVAL;
+	}
+
+	if (!data->hdev->ll_driver) {
+		hid_err(data->hdev, "data->hdev->ll_driver == NULL\n");
+		return -EINVAL;
+	}
+
+	m = convert_magnitude(data->rumble.strong_magnitude);
+	if (m != data->rumble_left) {
+		int ret;
+
+		buf[0] = 0x02;
+		buf[1] = 0x01;
+		buf[2] = 0xbf;
+		buf[3] = 0x00;
+		buf[4] = 0x00;
+		buf[5] = 0x03;
+		buf[6] = 0x49;
+		buf[7] = 0x00;
+		buf[8] = m;
+		buf[9] = 0x00;
+		buf[10] = 0;
+		buf[11] = 0;
+		buf[12] = 0;
+		buf[13] = 0;
+
+		ret = hid_hw_output_report(data->hdev, buf, 14);
+		if (ret < 0) {
+			hid_err(data->hdev, "error %d (%*ph)\n", ret, 14, buf);
+			return ret;
+		}
+		data->rumble_left = m;
+	}
+
+	m = convert_magnitude(data->rumble.weak_magnitude);
+	if (m != data->rumble_right) {
+		int ret;
+
+		buf[0] = 0x02;
+		buf[1] = 0x03;
+		buf[2] = 0xbf;
+		buf[3] = 0x00;
+		buf[4] = 0x00;
+		buf[5] = 0x03;
+		buf[6] = 0x49;
+		buf[7] = 0x00;
+		buf[8] = m;
+		buf[9] = 0x00;
+		buf[10] = 0;
+		buf[11] = 0;
+		buf[12] = 0;
+		buf[13] = 0;
+
+		ret = hid_hw_output_report(data->hdev, buf, 14);
+		if (ret < 0) {
+			hid_err(data->hdev, "error %d (%*ph)\n", ret, 14, buf);
+			return ret;
+		}
+		data->rumble_right = m;
+	}
+
+	return 0;
+}
+
+
+static void winwing_haptic_rumble_cb(struct work_struct *work)
+{
+	struct winwing_drv_data *data;
+
+	data = container_of(work, struct winwing_drv_data, rumble_work);
+
+	if (data)
+		winwing_haptic_rumble(data);
+}
+
+static int winwing_play_effect(struct input_dev *dev, void *context,
+		struct ff_effect *effect)
+{
+	struct winwing_drv_data *data = (struct winwing_drv_data *) context;
+
+	if (effect->type != FF_RUMBLE)
+		return 0;
+
+	if (!data)
+		return -EINVAL;
+
+	data->rumble = effect->u.rumble;
+
+	return schedule_work(&data->rumble_work);
+}
+
+static int winwing_init_ff(struct hid_device *hdev, struct hid_input *hidinput)
+{
+	struct winwing_drv_data *data;
+
+	data = (struct winwing_drv_data *) hid_get_drvdata(hdev);
+	data->report_rumble = devm_kzalloc(&hdev->dev, MAX_REPORT, GFP_KERNEL);
+	data->rumble_left = -1;
+	data->rumble_right = -1;
+
+	input_set_capability(hidinput->input, EV_FF, FF_RUMBLE);
+
+	if (!data)
+		return -EINVAL;
+
+	return input_ff_create_memless(hidinput->input, data,
+			winwing_play_effect);
+}
+
 static int winwing_probe(struct hid_device *hdev,
 		const struct hid_device_id *id)
 {
@@ -219,10 +361,12 @@ static int winwing_probe(struct hid_device *hdev,
 	if (!data)
 		return -ENOMEM;
 
-	data->map_more_buttons = id->driver_data;
-
+	data->hdev = hdev;
+	data->has_grip15 = id->driver_data;
 	hid_set_drvdata(hdev, data);
 
+	INIT_WORK(&data->rumble_work, winwing_haptic_rumble_cb);
+
 	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
 	if (ret) {
 		hid_err(hdev, "hw start failed\n");
@@ -232,19 +376,39 @@ static int winwing_probe(struct hid_device *hdev,
 	return 0;
 }
 
+static void winwing_remove(struct hid_device *hdev)
+{
+	struct winwing_drv_data *data;
+
+	data = (struct winwing_drv_data *) hid_get_drvdata(hdev);
+
+	if (data)
+		cancel_work_sync(&data->rumble_work);
+
+	hid_hw_close(hdev);
+	hid_hw_stop(hdev);
+}
+
 static int winwing_input_configured(struct hid_device *hdev,
 		struct hid_input *hidinput)
 {
+	struct winwing_drv_data *data;
 	int ret;
 
+	data = (struct winwing_drv_data *) hid_get_drvdata(hdev);
+
 	ret = winwing_init_led(hdev, hidinput->input);
 
 	if (ret)
 		hid_err(hdev, "led init failed\n");
 
+	if (data->has_grip15)
+		winwing_init_ff(hdev, hidinput);
+
 	return ret;
 }
 
+/* Set driver_data to 1 for grips with rumble motor and more than 32 buttons */
 static const struct hid_device_id winwing_devices[] = {
 	{ HID_USB_DEVICE(0x4098, 0xbd65), .driver_data = 1 },  /* TGRIP-15E  */
 	{ HID_USB_DEVICE(0x4098, 0xbd64), .driver_data = 1 },  /* TGRIP-15EX */
@@ -261,6 +425,7 @@ static struct hid_driver winwing_driver = {
 	.input_configured = winwing_input_configured,
 	.input_mapping = winwing_input_mapping,
 	.probe = winwing_probe,
+	.remove = winwing_remove,
 };
 module_hid_driver(winwing_driver);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH RESEND] HID: winwing: Enable rumble effects
  2026-02-11  5:31 [PATCH RESEND] HID: winwing: Enable rumble effects Ivan Gorinov
@ 2026-02-12  5:31 ` Dan Carpenter
  0 siblings, 0 replies; 2+ messages in thread
From: Dan Carpenter @ 2026-02-12  5:31 UTC (permalink / raw)
  To: oe-kbuild, Ivan Gorinov, Jiri Kosina
  Cc: lkp, oe-kbuild-all, linux-input, linux-kernel

Hi Ivan,

kernel test robot noticed the following build warnings:

https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ivan-Gorinov/HID-winwing-Enable-rumble-effects/20260211-133322
base:   https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git for-next
patch link:    https://lore.kernel.org/r/20260211053116.GA20357%40altimeter-info
patch subject: [PATCH RESEND] HID: winwing: Enable rumble effects
config: parisc-randconfig-r071-20260211 (https://download.01.org/0day-ci/archive/20260212/202602120209.xYKh9QQp-lkp@intel.com/config)
compiler: hppa-linux-gcc (GCC) 8.5.0
smatch version: v0.5.0-8994-gd50c5a4c

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
| Closes: https://lore.kernel.org/r/202602120209.xYKh9QQp-lkp@intel.com/

smatch warnings:
drivers/hid/hid-winwing.c:235 winwing_haptic_rumble() warn: address of NULL pointer 'data->hdev'
drivers/hid/hid-winwing.c:308 winwing_haptic_rumble_cb() warn: can 'data' even be NULL?
drivers/hid/hid-winwing.c:339 winwing_init_ff() warn: variable dereferenced before check 'data' (see line 333)

vim +235 drivers/hid/hid-winwing.c

c4c97b07cd09c03 Ivan Gorinov 2026-02-11  221  static int winwing_haptic_rumble(struct winwing_drv_data *data)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  222  {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  223  	__u8 *buf;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  224  	__u8 m;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  225  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  226  	if (!data)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  227  		return -EINVAL;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  228  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  229  	buf = data->report_rumble;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  230  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  231  	if (!buf)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  232  		return -EINVAL;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  233  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  234  	if (!data->hdev) {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 @235  		hid_err(data->hdev, "data->hdev == NULL\n");
                                                                ^^^^^^^^^^
This doesn't end up getting dereferenced because of dev_err() magic
but passing a NULL here is pointless.

c4c97b07cd09c03 Ivan Gorinov 2026-02-11  236  		return -EINVAL;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  237  	}
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  238  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  239  	if (!data->hdev->ll_driver) {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  240  		hid_err(data->hdev, "data->hdev->ll_driver == NULL\n");
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  241  		return -EINVAL;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  242  	}
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  243  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  244  	m = convert_magnitude(data->rumble.strong_magnitude);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  245  	if (m != data->rumble_left) {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  246  		int ret;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  247  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  248  		buf[0] = 0x02;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  249  		buf[1] = 0x01;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  250  		buf[2] = 0xbf;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  251  		buf[3] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  252  		buf[4] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  253  		buf[5] = 0x03;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  254  		buf[6] = 0x49;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  255  		buf[7] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  256  		buf[8] = m;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  257  		buf[9] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  258  		buf[10] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  259  		buf[11] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  260  		buf[12] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  261  		buf[13] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  262  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  263  		ret = hid_hw_output_report(data->hdev, buf, 14);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  264  		if (ret < 0) {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  265  			hid_err(data->hdev, "error %d (%*ph)\n", ret, 14, buf);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  266  			return ret;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  267  		}
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  268  		data->rumble_left = m;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  269  	}
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  270  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  271  	m = convert_magnitude(data->rumble.weak_magnitude);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  272  	if (m != data->rumble_right) {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  273  		int ret;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  274  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  275  		buf[0] = 0x02;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  276  		buf[1] = 0x03;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  277  		buf[2] = 0xbf;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  278  		buf[3] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  279  		buf[4] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  280  		buf[5] = 0x03;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  281  		buf[6] = 0x49;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  282  		buf[7] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  283  		buf[8] = m;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  284  		buf[9] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  285  		buf[10] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  286  		buf[11] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  287  		buf[12] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  288  		buf[13] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  289  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  290  		ret = hid_hw_output_report(data->hdev, buf, 14);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  291  		if (ret < 0) {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  292  			hid_err(data->hdev, "error %d (%*ph)\n", ret, 14, buf);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  293  			return ret;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  294  		}
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  295  		data->rumble_right = m;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  296  	}
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  297  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  298  	return 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  299  }
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  300  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  301  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  302  static void winwing_haptic_rumble_cb(struct work_struct *work)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  303  {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  304  	struct winwing_drv_data *data;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  305  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  306  	data = container_of(work, struct winwing_drv_data, rumble_work);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  307  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 @308  	if (data)

"data" can't be NULL.  It's work minus an offset.

c4c97b07cd09c03 Ivan Gorinov 2026-02-11  309  		winwing_haptic_rumble(data);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  310  }
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  311  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  312  static int winwing_play_effect(struct input_dev *dev, void *context,
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  313  		struct ff_effect *effect)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  314  {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  315  	struct winwing_drv_data *data = (struct winwing_drv_data *) context;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  316  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  317  	if (effect->type != FF_RUMBLE)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  318  		return 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  319  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  320  	if (!data)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  321  		return -EINVAL;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  322  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  323  	data->rumble = effect->u.rumble;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  324  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  325  	return schedule_work(&data->rumble_work);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  326  }
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  327  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  328  static int winwing_init_ff(struct hid_device *hdev, struct hid_input *hidinput)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  329  {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  330  	struct winwing_drv_data *data;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  331  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  332  	data = (struct winwing_drv_data *) hid_get_drvdata(hdev);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 @333  	data->report_rumble = devm_kzalloc(&hdev->dev, MAX_REPORT, GFP_KERNEL);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  334  	data->rumble_left = -1;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  335  	data->rumble_right = -1;
                                                ^^^^^^^^^^^^^^^^^^
Dereferences here.

c4c97b07cd09c03 Ivan Gorinov 2026-02-11  336  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  337  	input_set_capability(hidinput->input, EV_FF, FF_RUMBLE);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  338  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 @339  	if (!data)
                                                    ^^^^^^
Checked too late.

c4c97b07cd09c03 Ivan Gorinov 2026-02-11  340  		return -EINVAL;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  341  
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  342  	return input_ff_create_memless(hidinput->input, data,
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  343  			winwing_play_effect);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11  344  }

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-02-12  5:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-11  5:31 [PATCH RESEND] HID: winwing: Enable rumble effects Ivan Gorinov
2026-02-12  5:31 ` Dan Carpenter

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