lkml.org 
[lkml]   [2005]   [Jul]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: [PATCH] Add Force Feedback interface to joydev
    On Fri, Apr 08, 2005 at 08:29:52PM +0300, Anssi Hannula wrote:
    > This patch adds Force Feedback interface to joydev. I felt this
    > necessary because games usually don't run as root while evdev usually
    > can't be read or written by anyone else. Patch is against 2.6.12-rc2. If
    > there is a reason this can't be applied or needs modifications, please
    > say it :)

    Modern distros usually chown() the event devices to the user logged on
    the console, so this shouldn't be a problem. Anyway, I'm not opposed to
    adding the ioctl()s, but you should also add 64-bit compatible versions
    of them.

    >
    > If I have enough time and skills, I will start developing userspace
    > Force Feedback library, which would do (among other things) all
    > necessary force convertings between joystick, gamepad and wheel controllers.
    >
    > Does anyone have any thoughts about this?
    >
    > Signed-off-by: Anssi Hannula <anssi.hannula@mbnet.fi>
    >

    > diff -Nurp linux-2.6.11/Documentation/input/ff.txt linux-2.6.11-ffjoy/Documentation/input/ff.txt
    > --- linux-2.6.11/Documentation/input/ff.txt 2005-03-02 09:38:12.000000000 +0200
    > +++ linux-2.6.11-ffjoy/Documentation/input/ff.txt 2005-04-08 00:07:50.000000000 +0300
    > @@ -1,5 +1,6 @@
    > Force feedback for Linux.
    > By Johann Deneux <deneux@ifrance.com> on 2001/04/22.
    > +Updated & cleaned on 2005/04/04 by Anssi Hannula <anssi.hannula@gmail.com>
    > You may redistribute this file. Please remember to include shape.fig and
    > interactive.fig as well.
    > ----------------------------------------------------------------------------
    > @@ -10,18 +11,11 @@ This document describes how to use force
    > 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
    > effects.
    > -At the moment, only I-Force devices are supported, and not officially. That
    > -means I had to find out how the protocol works on my own. Of course, the
    > -information I managed to grasp is far from being complete, and I can not
    > -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.
    > +Please read joystick.txt before reading further this document.
    >
    > 2. Instructions to the user
    > ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    > -Here are instructions on how to compile and use the driver. In fact, this
    > -driver is the normal iforce, input and evdev drivers written by Vojtech
    > -Pavlik, plus additions to support force feedback.
    > +Here are instructions on how to compile and use the driver.
    >
    > 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".
    > @@ -29,19 +23,18 @@ To stop this annoying behaviour, move yo
    > should keep a hand on your device, in order to avoid it to brake down if
    > something goes wrong.
    >
    > -At the kernel's compilation:
    > - - Enable IForce/Serial
    > - - Enable Event interface
    > +At the kernel's compilation enable the Force Feedback support for devices you
    > +have.
    >
    > Compile the modules, install them.
    >
    > -You also need inputattach.
    > +For serial devices 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
    > +% modprobe iforce # Example of FF driver
    > +% modprobe evdev # For evdev-interface
    > % ./inputattach -ifor $2 & # Only for serial
    > If you are using USB, you don't need the inputattach step.
    >
    > @@ -66,23 +59,37 @@ mknod input/event3 c 13 67
    > 2.1 Does it work ?
    > ~~~~~~~~~~~~~~~~~~
    > There is an utility called fftest that will allow you to test the driver.
    > +% fftest /dev/input/jsXX
    > +
    > +You can test the evdev interface with:
    > % fftest /dev/input/eventXX
    >
    > +Please note that joydev (jsXX) interface is recommended over evdev due to
    > +security issues involved in allowing users to access evdev devices.
    > +
    > 3. Instructions to the developper
    > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    > - 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.
    > +All interactions are done using the joydev API. That is, you can use ioctl()
    > +and write() on /dev/input/jsXX. There is also an evdev interface on
    > +/dev/input/eventXX.
    > +
    > +Joydev FF API is present in JS_VERSION >= 0x020200.
    > +Evdev FF API is present in all 2.6 series kernels.
    > +Use the joydev API instead of evdev whenever possible.
    > +
    > +This information is subject to change.
    >
    > 3.1 Querying device capabilities
    > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    > #include <linux/input.h>
    > +#include <linux/joystick.h>
    > #include <sys/ioctl.h>
    >
    > unsigned long features[1 + FF_MAX/sizeof(unsigned long)];
    > int ioctl(int file_descriptor, int request, unsigned long *features);
    >
    > -"request" must be EVIOCGBIT(EV_FF, size of features array in bytes )
    > +"request" must be JSIOCGFFBIT(size of features array in bytes).
    > +The evdev version is EVIOCGBIT(EV_FF, size of features array in bytes ).
    >
    > Returns the features supported by the device. features is a bitfield with the
    > following bits:
    > @@ -100,6 +107,7 @@ following bits:
    > - FF_INERTIA can simulate inertia
    >
    >
    > +int ioctl(int fd, JSIOCGEFFECTS, int *n);
    > int ioctl(int fd, EVIOCGEFFECTS, int *n);
    >
    > Returns the number of effects the device can keep in its memory.
    > @@ -107,11 +115,12 @@ Returns the number of effects the device
    > 3.2 Uploading effects to the device
    > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    > #include <linux/input.h>
    > +#include <linux/joystick.h>
    > #include <sys/ioctl.h>
    >
    > int ioctl(int file_descriptor, int request, struct ff_effect *effect);
    >
    > -"request" must be EVIOCSFF.
    > +"request" must be JSIOCSFF (EVIOCSFF for evdev).
    >
    > "effect" points to a structure describing the effect to upload. The effect is
    > uploaded, but not played.
    > @@ -126,6 +135,7 @@ You need xfig to visualize these files.
    >
    > 3.3 Removing an effect from the device
    > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    > +int ioctl(int fd, JSIOCRMFF, 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
    > @@ -136,6 +146,7 @@ stop the effect if it was playing.
    > Control of playing is done with write(). Below is an example:
    >
    > #include <linux/input.h>
    > +#include <linux/joystick.h>
    > #include <unistd.h>
    >
    > struct input_event play;
    > @@ -143,7 +154,7 @@ Control of playing is done with write().
    > struct ff_effect effect;
    > int fd;
    > ...
    > - fd = open("/dev/input/eventXX", O_RDWR);
    > + fd = open("/dev/input/jsXX", O_RDWR);
    > ...
    > /* Play three times */
    > play.type = EV_FF;
    > @@ -207,8 +218,11 @@ case, the driver stops the effect, up-lo
    >
    > 3.8 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:
    > +Every time the status of an effect is changed, an event is sent.
    > +
    > +NOTE: This appears to not be implemented in all drivers at the moment.
    > +
    > +The values and meanings of the fields of the event are as follows:
    > struct input_event {
    > /* When the status of the effect changed */
    > struct timeval time;
    > diff -Nurp linux-2.6.11/drivers/input/joydev.c linux-2.6.11-ffjoy/drivers/input/joydev.c
    > --- linux-2.6.11/drivers/input/joydev.c 2005-04-07 23:57:21.000000000 +0300
    > +++ linux-2.6.11-ffjoy/drivers/input/joydev.c 2005-04-08 00:04:40.000000000 +0300
    > @@ -141,6 +141,13 @@ static int joydev_fasync(int fd, struct
    > return retval < 0 ? retval : 0;
    > }
    >
    > +static int joydev_flush(struct file * file)
    > +{
    > + struct joydev_list *list = file->private_data;
    > + if (!list->joydev->exist) return -ENODEV;
    > + return input_flush_device(&list->joydev->handle, file);
    > +}
    > +
    > static void joydev_free(struct joydev *joydev)
    > {
    > joydev_table[joydev->minor] = NULL;
    > @@ -191,7 +198,21 @@ static int joydev_open(struct inode *ino
    >
    > static ssize_t joydev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
    > {
    > - return -EINVAL;
    > + struct joydev_list *list = file->private_data;
    > + struct input_event event;
    > + int retval = 0;
    > +
    > + if (!list->joydev->exist) return -ENODEV;
    > +
    > + while (retval < count) {
    > +
    > + if (copy_from_user(&event, buffer + retval, sizeof(struct input_event)))
    > + return -EFAULT;
    > + input_event(list->joydev->handle.dev, event.type, event.code, event.value);
    > + retval += sizeof(struct input_event);
    > + }
    > +
    > + return retval;
    > }
    >
    > static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
    > @@ -358,6 +379,26 @@ static int joydev_ioctl(struct inode *in
    > case JSIOCGBTNMAP:
    > return copy_to_user(argp, joydev->keypam,
    > sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0;
    > + case JSIOCSFF:
    > + if (dev->upload_effect) {
    > + struct ff_effect effect;
    > + int err;
    > + if (copy_from_user(&effect, argp, sizeof(effect)))
    > + return -EFAULT;
    > + err = dev->upload_effect(dev, &effect);
    > + if (put_user(effect.id, &(((struct ff_effect __user *)arg)->id)))
    > + return -EFAULT;
    > + return err;
    > + }
    > + else return -ENOSYS;
    > + case JSIOCRMFF:
    > + if (dev->erase_effect)
    > + return dev->erase_effect(dev, (int)arg);
    > + return -ENOSYS;
    > + case JSIOCGEFFECTS:
    > + if (put_user(dev->ff_effects_max, (int __user *)arg))
    > + return -EFAULT;
    > + return 0;
    > default:
    > if ((cmd & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) == JSIOCGNAME(0)) {
    > int len;
    > @@ -367,6 +408,15 @@ static int joydev_ioctl(struct inode *in
    > if (copy_to_user(argp, dev->name, len)) return -EFAULT;
    > return len;
    > }
    > + if (_IOC_NR(cmd) == _IOC_NR(JSIOCGFFBIT(0))) {
    > + int len;
    > + len = NBITS(FF_MAX) * sizeof(long);
    > + if (len > _IOC_SIZE(cmd))
    > + len = _IOC_SIZE(cmd);
    > + if (copy_to_user(argp, dev->ffbit, len))
    > + return -EFAULT;
    > + return len;
    > + }
    > }
    > return -EINVAL;
    > }
    > @@ -380,6 +430,7 @@ static struct file_operations joydev_fop
    > .release = joydev_release,
    > .ioctl = joydev_ioctl,
    > .fasync = joydev_fasync,
    > + .flush = joydev_flush,
    > };
    >
    > static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
    > diff -Nurp linux-2.6.11/include/linux/joystick.h linux-2.6.11-ffjoy/include/linux/joystick.h
    > --- linux-2.6.11/include/linux/joystick.h 2005-04-07 23:57:42.000000000 +0300
    > +++ linux-2.6.11-ffjoy/include/linux/joystick.h 2005-04-07 23:59:59.000000000 +0300
    > @@ -36,7 +36,7 @@
    > * Version
    > */
    >
    > -#define JS_VERSION 0x020100
    > +#define JS_VERSION 0x020200
    >
    > /*
    > * Types and constants for reading from /dev/js
    > @@ -71,6 +71,13 @@ struct js_event {
    > #define JSIOCSBTNMAP _IOW('j', 0x33, __u16[KEY_MAX - BTN_MISC + 1]) /* set button mapping */
    > #define JSIOCGBTNMAP _IOR('j', 0x34, __u16[KEY_MAX - BTN_MISC + 1]) /* get button mapping */
    >
    > +#define JSIOCGFFBIT(len) _IOC(_IOC_READ, 'j', 0x41, len) /* get force effect bits */
    > +#define JSIOCSFF _IOW('j', 0x42, struct ff_effect)
    > + /* upload a force effect to a force feedback device */
    > +#define JSIOCRMFF _IOW('j', 0x43, int) /* erase a force effect */
    > +#define JSIOCGEFFECTS _IOR('j', 0x44, int)
    > + /* get number of effects playable at the same time */
    > +
    > /*
    > * Types and constants for get/set correction
    > */
    >


    --
    Vojtech Pavlik
    SuSE Labs, SuSE CR
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-07-07 15:49    [W:0.045 / U:149.988 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site