All of lore.kernel.org
 help / color / mirror / Atom feed
* First attempt to get uinput connected with ff-memless
@ 2016-04-29 17:19 Manuel Reimer
  0 siblings, 0 replies; only message in thread
From: Manuel Reimer @ 2016-04-29 17:19 UTC (permalink / raw)
  To: linux-input

[-- Attachment #1: Type: text/plain, Size: 817 bytes --]

Hello,

attached is a try to get the uinput driver connected with ff-memless.

The idea behind this is, that this would allow uinput drivers to use 
this kernel built-in logic.

My attempt is pretty simple and seems to miss something important. I'm 
no kernel hacker, so I don't know what's the problem.

If I listen on a serial console, then I'm able to catch many messages 
like this:

[  364.431753] bad: scheduling from the idle thread!
[  364.490514] bad: scheduling from the idle thread!
[  364.527516] bad: scheduling from the idle thread!

If I try to Ctrl+C the running and hanging fftest, then the whole system 
freezes.

My simple idea was "Just upload the rumble effect and play it 
immediately afterwards", but it seems to be not that simple to do this...

Maybe someone can have a look at this.

Manuel

[-- Attachment #2: uinput_ff_memless.patch --]
[-- Type: text/x-patch, Size: 2535 bytes --]

--- uinput.c.org	2016-04-29 19:13:08.135810778 +0200
+++ uinput.c	2016-04-29 18:54:44.732493058 +0200
@@ -225,16 +225,43 @@ static int uinput_dev_erase_effect(struc
 		return -ENOSYS;
 
 	request.code = UI_FF_ERASE;
 	request.u.effect_id = effect_id;
 
 	return uinput_request_submit(udev, &request);
 }
 
+/* Callback for ff-memless. Uploads effect and immediately plays it */
+static int uinput_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
+{
+	uinput_dev_upload_effect(dev, effect, NULL);
+	uinput_dev_playback(dev, effect->id, 1);
+    return 0;
+}
+
+static int uinput_is_memless_device(struct uinput_device *udev)
+{
+	/*
+	 * A device is expected to be memless if it only supports one effect
+	 * simultaneously and FF_RUMBLE is the only supported effect
+	 */
+
+	if (udev->ff_effects_max != 1)
+		return 0;
+
+	DECLARE_BITMAP(ui_scratch, FF_CNT);
+	bitmap_zero(ui_scratch, FF_CNT);
+	set_bit(FF_RUMBLE, ui_scratch);
+	if (!bitmap_equal(ui_scratch, udev->dev->ffbit, FF_CNT))
+		return 0;
+
+	return 1;
+}
+
 static void uinput_destroy_device(struct uinput_device *udev)
 {
 	const char *name, *phys;
 	struct input_dev *dev = udev->dev;
 	enum uinput_state old_state = udev->state;
 
 	udev->state = UIST_NEW_DEVICE;
 
@@ -275,25 +302,33 @@ static int uinput_create_device(struct u
 	if (test_bit(EV_FF, dev->evbit) && !udev->ff_effects_max) {
 		printk(KERN_DEBUG "%s: ff_effects_max should be non-zero when FF_BIT is set\n",
 			UINPUT_NAME);
 		error = -EINVAL;
 		goto fail1;
 	}
 
 	if (udev->ff_effects_max) {
-		error = input_ff_create(dev, udev->ff_effects_max);
-		if (error)
-			goto fail1;
-
-		dev->ff->upload = uinput_dev_upload_effect;
-		dev->ff->erase = uinput_dev_erase_effect;
-		dev->ff->playback = uinput_dev_playback;
-		dev->ff->set_gain = uinput_dev_set_gain;
-		dev->ff->set_autocenter = uinput_dev_set_autocenter;
+		if (uinput_is_memless_device(udev)) {
+	        input_set_capability(dev, EV_FF, FF_RUMBLE);
+			error = input_ff_create_memless(dev, NULL, uinput_play_effect);
+			if (error)
+				goto fail1;
+		}
+		else {
+			error = input_ff_create(dev, udev->ff_effects_max);
+			if (error)
+				goto fail1;
+
+			dev->ff->upload = uinput_dev_upload_effect;
+			dev->ff->erase = uinput_dev_erase_effect;
+			dev->ff->playback = uinput_dev_playback;
+			dev->ff->set_gain = uinput_dev_set_gain;
+			dev->ff->set_autocenter = uinput_dev_set_autocenter;
+		}
 	}
 
 	error = input_register_device(udev->dev);
 	if (error)
 		goto fail2;
 
 	udev->state = UIST_CREATED;
 

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2016-04-29 17:19 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-29 17:19 First attempt to get uinput connected with ff-memless Manuel Reimer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.