Commit 3057d509 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab Committed by Dmitry Torokhov

Input: convert force feedback documentation into ReST format

This file require minimum adjustments to be a valid ReST file.
Do it, in order to be able to parse it with Sphinx.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent acbdca8b
Force feedback for Linux.
By Johann Deneux <johann.deneux@gmail.com> on 2001/04/22.
Updated by Anssi Hannula <anssi.hannula@gmail.com> on 2006/04/09.
========================
Force feedback for Linux
========================
:Author: Johann Deneux <johann.deneux@gmail.com> on 2001/04/22.
:Updated: Anssi Hannula <anssi.hannula@gmail.com> on 2006/04/09.
You may redistribute this file. Please remember to include shape.fig and
interactive.fig as well.
----------------------------------------------------------------------------
1. Introduction
~~~~~~~~~~~~~~~
Introduction
~~~~~~~~~~~~
This document describes how to use force feedback devices under Linux. The
goal is not to support these devices as if they were simple input-only devices
(as it is already the case), but to really enable the rendering of force
......@@ -15,8 +19,9 @@ This document only describes the force feedback part of the Linux input
interface. Please read joystick.txt and input.txt before reading further this
document.
2. Instructions to the user
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Instructions to the user
~~~~~~~~~~~~~~~~~~~~~~~~
To enable force feedback, you have to:
1. have your kernel configured with evdev and a driver that supports your
......@@ -33,39 +38,48 @@ something goes wrong.
If you have a serial iforce device, you need to start inputattach. See
joystick.txt for details.
2.1 Does it work ?
~~~~~~~~~~~~~~~~~~
There is an utility called fftest that will allow you to test the driver.
% fftest /dev/input/eventXX
Does it work ?
--------------
There is an utility called fftest that will allow you to test the driver::
% fftest /dev/input/eventXX
Instructions to the developer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3. Instructions to the developer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
All interactions are done using the event API. That is, you can use ioctl()
and write() on /dev/input/eventXX.
This information is subject to change.
3.1 Querying device capabilities
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <linux/input.h>
#include <sys/ioctl.h>
Querying device capabilities
----------------------------
#define BITS_TO_LONGS(x) \
(((x) + 8 * sizeof (unsigned long) - 1) / (8 * sizeof (unsigned long)))
unsigned long features[BITS_TO_LONGS(FF_CNT)];
int ioctl(int file_descriptor, int request, unsigned long *features);
::
#include <linux/input.h>
#include <sys/ioctl.h>
#define BITS_TO_LONGS(x) \
(((x) + 8 * sizeof (unsigned long) - 1) / (8 * sizeof (unsigned long)))
unsigned long features[BITS_TO_LONGS(FF_CNT)];
int ioctl(int file_descriptor, int request, unsigned long *features);
"request" must be EVIOCGBIT(EV_FF, size of features array in bytes )
Returns the features supported by the device. features is a bitfield with the
following bits:
- FF_CONSTANT can render constant force effects
- FF_PERIODIC can render periodic effects with the following waveforms:
- FF_SQUARE square waveform
- FF_TRIANGLE triangle waveform
- FF_SINE sine waveform
- FF_SAW_UP sawtooth up waveform
- FF_SAW_DOWN sawtooth down waveform
- FF_CUSTOM custom waveform
- FF_RAMP can render ramp effects
- FF_SPRING can simulate the presence of a spring
- FF_FRICTION can simulate friction
......@@ -75,24 +89,30 @@ following bits:
- FF_GAIN gain is adjustable
- FF_AUTOCENTER autocenter is adjustable
Note: In most cases you should use FF_PERIODIC instead of FF_RUMBLE. All
.. note::
- In most cases you should use FF_PERIODIC instead of FF_RUMBLE. All
devices that support FF_RUMBLE support FF_PERIODIC (square, triangle,
sine) and the other way around.
Note: The exact syntax FF_CUSTOM is undefined for the time being as no driver
- The exact syntax FF_CUSTOM is undefined for the time being as no driver
supports it yet.
::
int ioctl(int fd, EVIOCGEFFECTS, int *n);
int ioctl(int fd, EVIOCGEFFECTS, int *n);
Returns the number of effects the device can keep in its memory.
3.2 Uploading effects to the device
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <linux/input.h>
#include <sys/ioctl.h>
Uploading effects to the device
-------------------------------
::
int ioctl(int file_descriptor, int request, struct ff_effect *effect);
#include <linux/input.h>
#include <sys/ioctl.h>
int ioctl(int file_descriptor, int request, struct ff_effect *effect);
"request" must be EVIOCSFF.
......@@ -110,34 +130,41 @@ See <linux/input.h> for a description of the ff_effect struct. You should also
find help in a few sketches, contained in files shape.fig and interactive.fig.
You need xfig to visualize these files.
3.3 Removing an effect from the device
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int ioctl(int fd, EVIOCRMFF, effect.id);
Removing an effect from the device
----------------------------------
::
int ioctl(int fd, EVIOCRMFF, effect.id);
This makes room for new effects in the device's memory. Note that this also
stops the effect if it was playing.
3.4 Controlling the playback of effects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Controlling the playback of effects
-----------------------------------
Control of playing is done with write(). Below is an example:
#include <linux/input.h>
#include <unistd.h>
::
#include <linux/input.h>
#include <unistd.h>
struct input_event play;
struct input_event stop;
struct ff_effect effect;
int fd;
...
...
fd = open("/dev/input/eventXX", O_RDWR);
...
...
/* Play three times */
play.type = EV_FF;
play.code = effect.id;
play.value = 3;
write(fd, (const void*) &play, sizeof(play));
...
...
/* Stop an effect */
stop.type = EV_FF;
stop.code = effect.id;
......@@ -145,43 +172,50 @@ Control of playing is done with write(). Below is an example:
write(fd, (const void*) &play, sizeof(stop));
3.5 Setting the gain
~~~~~~~~~~~~~~~~~~~~
Setting the gain
----------------
Not all devices have the same strength. Therefore, users should set a gain
factor depending on how strong they want effects to be. This setting is
persistent across access to the driver.
/* Set the gain of the device
int gain; /* between 0 and 100 */
struct input_event ie; /* structure used to communicate with the driver */
::
ie.type = EV_FF;
ie.code = FF_GAIN;
ie.value = 0xFFFFUL * gain / 100;
/* Set the gain of the device
int gain; /* between 0 and 100 */
struct input_event ie; /* structure used to communicate with the driver */
if (write(fd, &ie, sizeof(ie)) == -1)
ie.type = EV_FF;
ie.code = FF_GAIN;
ie.value = 0xFFFFUL * gain / 100;
if (write(fd, &ie, sizeof(ie)) == -1)
perror("set gain");
3.6 Enabling/Disabling autocenter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Enabling/Disabling autocenter
-----------------------------
The autocenter feature quite disturbs the rendering of effects in my opinion,
and I think it should be an effect, which computation depends on the game
type. But you can enable it if you want.
int autocenter; /* between 0 and 100 */
struct input_event ie;
::
ie.type = EV_FF;
ie.code = FF_AUTOCENTER;
ie.value = 0xFFFFUL * autocenter / 100;
int autocenter; /* between 0 and 100 */
struct input_event ie;
if (write(fd, &ie, sizeof(ie)) == -1)
ie.type = EV_FF;
ie.code = FF_AUTOCENTER;
ie.value = 0xFFFFUL * autocenter / 100;
if (write(fd, &ie, sizeof(ie)) == -1)
perror("set auto-center");
A value of 0 means "no auto-center".
3.7 Dynamic update of an effect
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dynamic update of an effect
---------------------------
Proceed as if you wanted to upload a new effect, except that instead of
setting the id field to -1, you set it to the wanted effect id.
Normally, the effect is not stopped and restarted. However, depending on the
......@@ -192,30 +226,32 @@ case, the driver stops the effect, up-load it, and restart it.
Therefore it is recommended to dynamically change direction while the effect
is playing only when it is ok to restart the effect with a replay count of 1.
3.8 Information about the status of effects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Information about the status of effects
---------------------------------------
Every time the status of an effect is changed, an event is sent. The values
and meanings of the fields of the event are as follows:
and meanings of the fields of the event are as follows::
struct input_event {
/* When the status of the effect changed */
struct timeval time;
struct input_event {
/* When the status of the effect changed */
struct timeval time;
/* Set to EV_FF_STATUS */
unsigned short type;
/* Set to EV_FF_STATUS */
unsigned short type;
/* Contains the id of the effect */
unsigned short code;
/* Contains the id of the effect */
unsigned short code;
/* Indicates the status */
unsigned int value;
};
/* Indicates the status */
unsigned int value;
};
FF_STATUS_STOPPED The effect stopped playing
FF_STATUS_PLAYING The effect started to play
FF_STATUS_STOPPED The effect stopped playing
FF_STATUS_PLAYING The effect started to play
.. note::
NOTE: Status feedback is only supported by iforce driver. If you have
- Status feedback is only supported by iforce driver. If you have
a really good reason to use this, please contact
linux-joystick@atrey.karlin.mff.cuni.cz or anssi.hannula@gmail.com
so that support for it can be added to the rest of the drivers.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment