mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-02-24 14:33:42 +00:00
Input: update the force feedback documentation
Signed-off-by: Anssi Hannula <anssi.hannula@gmail.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
parent
bb3caf7f43
commit
8b8277a174
@ -1,67 +1,37 @@
|
|||||||
Force feedback for Linux.
|
Force feedback for Linux.
|
||||||
By Johann Deneux <deneux@ifrance.com> on 2001/04/22.
|
By Johann Deneux <deneux@ifrance.com> on 2001/04/22.
|
||||||
|
Updated by Anssi Hannula <anssi.hannula@gmail.com> on 2006/04/09.
|
||||||
You may redistribute this file. Please remember to include shape.fig and
|
You may redistribute this file. Please remember to include shape.fig and
|
||||||
interactive.fig as well.
|
interactive.fig as well.
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
0. Introduction
|
1. Introduction
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
This document describes how to use force feedback devices under Linux. The
|
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
|
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
|
(as it is already the case), but to really enable the rendering of force
|
||||||
effects.
|
effects.
|
||||||
At the moment, only I-Force devices are supported, and not officially. That
|
This document only describes the force feedback part of the Linux input
|
||||||
means I had to find out how the protocol works on my own. Of course, the
|
interface. Please read joystick.txt and input.txt before reading further this
|
||||||
information I managed to grasp is far from being complete, and I can not
|
document.
|
||||||
guarranty that this driver will work for you.
|
|
||||||
This document only describes the force feedback part of the driver for I-Force
|
|
||||||
devices. Please read joystick.txt before reading further this document.
|
|
||||||
|
|
||||||
2. Instructions to the user
|
2. Instructions to the user
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Here are instructions on how to compile and use the driver. In fact, this
|
To enable force feedback, you have to:
|
||||||
driver is the normal iforce, input and evdev drivers written by Vojtech
|
|
||||||
Pavlik, plus additions to support force feedback.
|
1. have your kernel configured with evdev and a driver that supports your
|
||||||
|
device.
|
||||||
|
2. make sure evdev module is loaded and /dev/input/event* device files are
|
||||||
|
created.
|
||||||
|
|
||||||
Before you start, let me WARN you that some devices shake violently during the
|
Before you start, let me WARN you that some devices shake violently during the
|
||||||
initialisation phase. This happens for example with my "AVB Top Shot Pegasus".
|
initialisation phase. This happens for example with my "AVB Top Shot Pegasus".
|
||||||
To stop this annoying behaviour, move you joystick to its limits. Anyway, you
|
To stop this annoying behaviour, move you joystick to its limits. Anyway, you
|
||||||
should keep a hand on your device, in order to avoid it to brake down if
|
should keep a hand on your device, in order to avoid it to break down if
|
||||||
something goes wrong.
|
something goes wrong.
|
||||||
|
|
||||||
At the kernel's compilation:
|
If you have a serial iforce device, you need to start inputattach. See
|
||||||
- Enable IForce/Serial
|
joystick.txt for details.
|
||||||
- Enable Event interface
|
|
||||||
|
|
||||||
Compile the modules, install them.
|
|
||||||
|
|
||||||
You also need inputattach.
|
|
||||||
|
|
||||||
You then need to insert the modules into the following order:
|
|
||||||
% modprobe joydev
|
|
||||||
% modprobe serport # Only for serial
|
|
||||||
% modprobe iforce
|
|
||||||
% modprobe evdev
|
|
||||||
% ./inputattach -ifor $2 & # Only for serial
|
|
||||||
If you are using USB, you don't need the inputattach step.
|
|
||||||
|
|
||||||
Please check that you have all the /dev/input entries needed:
|
|
||||||
cd /dev
|
|
||||||
rm js*
|
|
||||||
mkdir input
|
|
||||||
mknod input/js0 c 13 0
|
|
||||||
mknod input/js1 c 13 1
|
|
||||||
mknod input/js2 c 13 2
|
|
||||||
mknod input/js3 c 13 3
|
|
||||||
ln -s input/js0 js0
|
|
||||||
ln -s input/js1 js1
|
|
||||||
ln -s input/js2 js2
|
|
||||||
ln -s input/js3 js3
|
|
||||||
|
|
||||||
mknod input/event0 c 13 64
|
|
||||||
mknod input/event1 c 13 65
|
|
||||||
mknod input/event2 c 13 66
|
|
||||||
mknod input/event3 c 13 67
|
|
||||||
|
|
||||||
2.1 Does it work ?
|
2.1 Does it work ?
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
@ -70,9 +40,9 @@ There is an utility called fftest that will allow you to test the driver.
|
|||||||
|
|
||||||
3. Instructions to the developper
|
3. Instructions to the developper
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
All interactions are done using the event API. That is, you can use ioctl()
|
All interactions are done using the event API. That is, you can use ioctl()
|
||||||
and write() on /dev/input/eventXX.
|
and write() on /dev/input/eventXX.
|
||||||
This information is subject to change.
|
This information is subject to change.
|
||||||
|
|
||||||
3.1 Querying device capabilities
|
3.1 Querying device capabilities
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -86,18 +56,29 @@ int ioctl(int file_descriptor, int request, unsigned long *features);
|
|||||||
|
|
||||||
Returns the features supported by the device. features is a bitfield with the
|
Returns the features supported by the device. features is a bitfield with the
|
||||||
following bits:
|
following bits:
|
||||||
- FF_X has an X axis (usually joysticks)
|
|
||||||
- FF_Y has an Y axis (usually joysticks)
|
|
||||||
- FF_WHEEL has a wheel (usually sterring wheels)
|
|
||||||
- FF_CONSTANT can render constant force effects
|
- FF_CONSTANT can render constant force effects
|
||||||
- FF_PERIODIC can render periodic effects (sine, triangle, square...)
|
- 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_RAMP can render ramp effects
|
||||||
- FF_SPRING can simulate the presence of a spring
|
- FF_SPRING can simulate the presence of a spring
|
||||||
- FF_FRICTION can simulate friction
|
- FF_FRICTION can simulate friction
|
||||||
- FF_DAMPER can simulate damper effects
|
- FF_DAMPER can simulate damper effects
|
||||||
- FF_RUMBLE rumble effects (normally the only effect supported by rumble
|
- FF_RUMBLE rumble effects
|
||||||
pads)
|
|
||||||
- FF_INERTIA can simulate inertia
|
- FF_INERTIA can simulate inertia
|
||||||
|
- FF_GAIN gain is adjustable
|
||||||
|
- FF_AUTOCENTER autocenter is adjustable
|
||||||
|
|
||||||
|
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
|
||||||
|
supports it yet.
|
||||||
|
|
||||||
|
|
||||||
int ioctl(int fd, EVIOCGEFFECTS, int *n);
|
int ioctl(int fd, EVIOCGEFFECTS, int *n);
|
||||||
@ -108,7 +89,7 @@ Returns the number of effects the device can keep in its memory.
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
int ioctl(int file_descriptor, int request, struct ff_effect *effect);
|
int ioctl(int file_descriptor, int request, struct ff_effect *effect);
|
||||||
|
|
||||||
"request" must be EVIOCSFF.
|
"request" must be EVIOCSFF.
|
||||||
@ -120,6 +101,9 @@ to the unique id assigned by the driver. This data is required for performing
|
|||||||
some operations (removing an effect, controlling the playback).
|
some operations (removing an effect, controlling the playback).
|
||||||
This if field must be set to -1 by the user in order to tell the driver to
|
This if field must be set to -1 by the user in order to tell the driver to
|
||||||
allocate a new effect.
|
allocate a new effect.
|
||||||
|
|
||||||
|
Effects are file descriptor specific.
|
||||||
|
|
||||||
See <linux/input.h> for a description of the ff_effect struct. You should also
|
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.
|
find help in a few sketches, contained in files shape.fig and interactive.fig.
|
||||||
You need xfig to visualize these files.
|
You need xfig to visualize these files.
|
||||||
@ -128,8 +112,8 @@ You need xfig to visualize these files.
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
int ioctl(int fd, EVIOCRMFF, effect.id);
|
int ioctl(int fd, EVIOCRMFF, effect.id);
|
||||||
|
|
||||||
This makes room for new effects in the device's memory. Please note this won't
|
This makes room for new effects in the device's memory. Note that this also
|
||||||
stop the effect if it was playing.
|
stops the effect if it was playing.
|
||||||
|
|
||||||
3.4 Controlling the playback of effects
|
3.4 Controlling the playback of effects
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -149,22 +133,21 @@ Control of playing is done with write(). Below is an example:
|
|||||||
play.type = EV_FF;
|
play.type = EV_FF;
|
||||||
play.code = effect.id;
|
play.code = effect.id;
|
||||||
play.value = 3;
|
play.value = 3;
|
||||||
|
|
||||||
write(fd, (const void*) &play, sizeof(play));
|
write(fd, (const void*) &play, sizeof(play));
|
||||||
...
|
...
|
||||||
/* Stop an effect */
|
/* Stop an effect */
|
||||||
stop.type = EV_FF;
|
stop.type = EV_FF;
|
||||||
stop.code = effect.id;
|
stop.code = effect.id;
|
||||||
stop.value = 0;
|
stop.value = 0;
|
||||||
|
|
||||||
write(fd, (const void*) &play, sizeof(stop));
|
write(fd, (const void*) &play, sizeof(stop));
|
||||||
|
|
||||||
3.5 Setting the gain
|
3.5 Setting the gain
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
Not all devices have the same strength. Therefore, users should set a 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
|
factor depending on how strong they want effects to be. This setting is
|
||||||
persistent across access to the driver, so you should not care about it if
|
persistent across access to the driver.
|
||||||
you are writing games, as another utility probably already set this for you.
|
|
||||||
|
|
||||||
/* Set the gain of the device
|
/* Set the gain of the device
|
||||||
int gain; /* between 0 and 100 */
|
int gain; /* between 0 and 100 */
|
||||||
@ -204,11 +187,14 @@ type of device, not all parameters can be dynamically updated. For example,
|
|||||||
the direction of an effect cannot be updated with iforce devices. In this
|
the direction of an effect cannot be updated with iforce devices. In this
|
||||||
case, the driver stops the effect, up-load it, and restart it.
|
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
|
3.8 Information about the status of effects
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Every time the status of an effect is changed, an event is sent. The values
|
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 {
|
struct input_event {
|
||||||
/* When the status of the effect changed */
|
/* When the status of the effect changed */
|
||||||
struct timeval time;
|
struct timeval time;
|
||||||
@ -225,3 +211,9 @@ struct input_event {
|
|||||||
|
|
||||||
FF_STATUS_STOPPED The effect stopped playing
|
FF_STATUS_STOPPED The effect stopped playing
|
||||||
FF_STATUS_PLAYING The effect started to play
|
FF_STATUS_PLAYING The effect started to play
|
||||||
|
|
||||||
|
NOTE: 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.
|
||||||
|
|
||||||
|
@ -667,98 +667,167 @@ struct input_absinfo {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Structures used in ioctls to upload effects to a device
|
* Structures used in ioctls to upload effects to a device
|
||||||
* The first structures are not passed directly by using ioctls.
|
* They are pieces of a bigger structure (called ff_effect)
|
||||||
* They are sub-structures of the actually sent structure (called ff_effect)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All duration values are expressed in ms. Values above 32767 ms (0x7fff)
|
||||||
|
* should not be used and have unspecified results.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ff_replay - defines scheduling of the effect
|
||||||
|
* @length: duration of the effect
|
||||||
|
* @delay: delay before effect should start playing
|
||||||
|
*/
|
||||||
struct ff_replay {
|
struct ff_replay {
|
||||||
__u16 length; /* Duration of an effect in ms. All other times are also expressed in ms */
|
__u16 length;
|
||||||
__u16 delay; /* Time to wait before to start playing an effect */
|
__u16 delay;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ff_trigger - defines what triggers the effect
|
||||||
|
* @button: number of the button triggering the effect
|
||||||
|
* @interval: controls how soon the effect can be re-triggered
|
||||||
|
*/
|
||||||
struct ff_trigger {
|
struct ff_trigger {
|
||||||
__u16 button; /* Number of button triggering an effect */
|
__u16 button;
|
||||||
__u16 interval; /* Time to wait before an effect can be re-triggered (ms) */
|
__u16 interval;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ff_envelope - generic effect envelope
|
||||||
|
* @attack_length: duration of the attack (ms)
|
||||||
|
* @attack_level: level at the beginning of the attack
|
||||||
|
* @fade_length: duration of fade (ms)
|
||||||
|
* @fade_level: level at the end of fade
|
||||||
|
*
|
||||||
|
* The @attack_level and @fade_level are absolute values; when applying
|
||||||
|
* envelope force-feedback core will convert to positive/negative
|
||||||
|
* value based on polarity of the default level of the effect.
|
||||||
|
* Valid range for the attack and fade levels is 0x0000 - 0x7fff
|
||||||
|
*/
|
||||||
struct ff_envelope {
|
struct ff_envelope {
|
||||||
__u16 attack_length; /* Duration of attack (ms) */
|
__u16 attack_length;
|
||||||
__u16 attack_level; /* Level at beginning of attack */
|
__u16 attack_level;
|
||||||
__u16 fade_length; /* Duration of fade (ms) */
|
__u16 fade_length;
|
||||||
__u16 fade_level; /* Level at end of fade */
|
__u16 fade_level;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FF_CONSTANT */
|
/**
|
||||||
|
* struct ff_constant_effect - defines parameters of a constant effect
|
||||||
|
* @level: strength of the effect; may be negative
|
||||||
|
* @envelope: envelope data
|
||||||
|
*/
|
||||||
struct ff_constant_effect {
|
struct ff_constant_effect {
|
||||||
__s16 level; /* Strength of effect. Negative values are OK */
|
__s16 level;
|
||||||
struct ff_envelope envelope;
|
struct ff_envelope envelope;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FF_RAMP */
|
/**
|
||||||
|
* struct ff_ramp_effect - defines parameters of a ramp effect
|
||||||
|
* @start_level: beginning strength of the effect; may be negative
|
||||||
|
* @end_level: final strength of the effect; may be negative
|
||||||
|
* @envelope: envelope data
|
||||||
|
*/
|
||||||
struct ff_ramp_effect {
|
struct ff_ramp_effect {
|
||||||
__s16 start_level;
|
__s16 start_level;
|
||||||
__s16 end_level;
|
__s16 end_level;
|
||||||
struct ff_envelope envelope;
|
struct ff_envelope envelope;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FF_SPRING of FF_FRICTION */
|
/**
|
||||||
|
* struct ff_condition_effect - defines a spring or friction effect
|
||||||
|
* @right_saturation: maximum level when joystick moved all way to the right
|
||||||
|
* @left_saturation: same for the left side
|
||||||
|
* @right_coeff: controls how fast the force grows when the joystick moves
|
||||||
|
* to the right
|
||||||
|
* @left_coeff: same for the left side
|
||||||
|
* @deadband: size of the dead zone, where no force is produced
|
||||||
|
* @center: position of the dead zone
|
||||||
|
*/
|
||||||
struct ff_condition_effect {
|
struct ff_condition_effect {
|
||||||
__u16 right_saturation; /* Max level when joystick is on the right */
|
__u16 right_saturation;
|
||||||
__u16 left_saturation; /* Max level when joystick in on the left */
|
__u16 left_saturation;
|
||||||
|
|
||||||
__s16 right_coeff; /* Indicates how fast the force grows when the
|
__s16 right_coeff;
|
||||||
joystick moves to the right */
|
__s16 left_coeff;
|
||||||
__s16 left_coeff; /* Same for left side */
|
|
||||||
|
|
||||||
__u16 deadband; /* Size of area where no force is produced */
|
|
||||||
__s16 center; /* Position of dead zone */
|
|
||||||
|
|
||||||
|
__u16 deadband;
|
||||||
|
__s16 center;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FF_PERIODIC */
|
/**
|
||||||
|
* struct ff_periodic_effect - defines parameters of a periodic effect
|
||||||
|
* @waveform: kind of the effect (wave)
|
||||||
|
* @period: period of the wave (ms)
|
||||||
|
* @magnitude: peak value
|
||||||
|
* @offset: mean value of the wave (roughly)
|
||||||
|
* @phase: 'horizontal' shift
|
||||||
|
* @envelope: envelope data
|
||||||
|
* @custom_len: number of samples (FF_CUSTOM only)
|
||||||
|
* @custom_data: buffer of samples (FF_CUSTOM only)
|
||||||
|
*
|
||||||
|
* Known waveforms - FF_SQUARE, FF_TRIANGLE, FF_SINE, FF_SAW_UP,
|
||||||
|
* FF_SAW_DOWN, FF_CUSTOM. The exact syntax FF_CUSTOM is undefined
|
||||||
|
* for the time being as no driver supports it yet.
|
||||||
|
*
|
||||||
|
* Note: the data pointed by custom_data is copied by the driver.
|
||||||
|
* You can therefore dispose of the memory after the upload/update.
|
||||||
|
*/
|
||||||
struct ff_periodic_effect {
|
struct ff_periodic_effect {
|
||||||
__u16 waveform; /* Kind of wave (sine, square...) */
|
__u16 waveform;
|
||||||
__u16 period; /* in ms */
|
__u16 period;
|
||||||
__s16 magnitude; /* Peak value */
|
__s16 magnitude;
|
||||||
__s16 offset; /* Mean value of wave (roughly) */
|
__s16 offset;
|
||||||
__u16 phase; /* 'Horizontal' shift */
|
__u16 phase;
|
||||||
|
|
||||||
struct ff_envelope envelope;
|
struct ff_envelope envelope;
|
||||||
|
|
||||||
/* Only used if waveform == FF_CUSTOM */
|
__u32 custom_len;
|
||||||
__u32 custom_len; /* Number of samples */
|
__s16 *custom_data;
|
||||||
__s16 *custom_data; /* Buffer of samples */
|
|
||||||
/* Note: the data pointed by custom_data is copied by the driver. You can
|
|
||||||
* therefore dispose of the memory after the upload/update */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* FF_RUMBLE */
|
/**
|
||||||
/* Some rumble pads have two motors of different weight.
|
* struct ff_rumble_effect - defines parameters of a periodic effect
|
||||||
strong_magnitude represents the magnitude of the vibration generated
|
* @strong_magnitude: magnitude of the heavy motor
|
||||||
by the heavy motor.
|
* @weak_magnitude: magnitude of the light one
|
||||||
*/
|
*
|
||||||
|
* Some rumble pads have two motors of different weight. Strong_magnitude
|
||||||
|
* represents the magnitude of the vibration generated by the heavy one.
|
||||||
|
*/
|
||||||
struct ff_rumble_effect {
|
struct ff_rumble_effect {
|
||||||
__u16 strong_magnitude; /* Magnitude of the heavy motor */
|
__u16 strong_magnitude;
|
||||||
__u16 weak_magnitude; /* Magnitude of the light one */
|
__u16 weak_magnitude;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Structure sent through ioctl from the application to the driver
|
* struct ff_effect - defines force feedback effect
|
||||||
|
* @type: type of the effect (FF_CONSTANT, FF_PERIODIC, FF_RAMP, FF_SPRING,
|
||||||
|
* FF_FRICTION, FF_DAMPER, FF_RUMBLE, FF_INERTIA, or FF_CUSTOM)
|
||||||
|
* @id: an unique id assigned to an effect
|
||||||
|
* @direction: direction of the effect
|
||||||
|
* @trigger: trigger conditions (struct ff_trigger)
|
||||||
|
* @replay: scheduling of the effect (struct ff_replay)
|
||||||
|
* @u: effect-specific structure (one of ff_constant_effect, ff_ramp_effect,
|
||||||
|
* ff_periodic_effect, ff_condition_effect, ff_rumble_effect) further
|
||||||
|
* defining effect parameters
|
||||||
|
*
|
||||||
|
* This structure is sent through ioctl from the application to the driver.
|
||||||
|
* To create a new effect aplication should set its @id to -1; the kernel
|
||||||
|
* will return assigned @id which can later be used to update or delete
|
||||||
|
* this effect.
|
||||||
|
*
|
||||||
|
* Direction of the effect is encoded as follows:
|
||||||
|
* 0 deg -> 0x0000 (down)
|
||||||
|
* 90 deg -> 0x4000 (left)
|
||||||
|
* 180 deg -> 0x8000 (up)
|
||||||
|
* 270 deg -> 0xC000 (right)
|
||||||
*/
|
*/
|
||||||
struct ff_effect {
|
struct ff_effect {
|
||||||
__u16 type;
|
__u16 type;
|
||||||
/* Following field denotes the unique id assigned to an effect.
|
|
||||||
* If user sets if to -1, a new effect is created, and its id is returned in the same field
|
|
||||||
* Else, the user sets it to the effect id it wants to update.
|
|
||||||
*/
|
|
||||||
__s16 id;
|
__s16 id;
|
||||||
|
__u16 direction;
|
||||||
__u16 direction; /* Direction. 0 deg -> 0x0000 (down)
|
|
||||||
90 deg -> 0x4000 (left)
|
|
||||||
180 deg -> 0x8000 (up)
|
|
||||||
270 deg -> 0xC000 (right)
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct ff_trigger trigger;
|
struct ff_trigger trigger;
|
||||||
struct ff_replay replay;
|
struct ff_replay replay;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user