linux/drivers/input/ff-core.c
<<
>>
Prefs
   1/*
   2 *  Force feedback support for Linux input subsystem
   3 *
   4 *  Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>
   5 *  Copyright (c) 2006 Dmitry Torokhov <dtor@mail.ru>
   6 */
   7
   8/*
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License, or
  12 * (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22 */
  23
  24/* #define DEBUG */
  25
  26#include <linux/input.h>
  27#include <linux/module.h>
  28#include <linux/mutex.h>
  29#include <linux/sched.h>
  30#include <linux/slab.h>
  31
  32/*
  33 * Check that the effect_id is a valid effect and whether the user
  34 * is the owner
  35 */
  36static int check_effect_access(struct ff_device *ff, int effect_id,
  37                                struct file *file)
  38{
  39        if (effect_id < 0 || effect_id >= ff->max_effects ||
  40            !ff->effect_owners[effect_id])
  41                return -EINVAL;
  42
  43        if (file && ff->effect_owners[effect_id] != file)
  44                return -EACCES;
  45
  46        return 0;
  47}
  48
  49/*
  50 * Checks whether 2 effects can be combined together
  51 */
  52static inline int check_effects_compatible(struct ff_effect *e1,
  53                                           struct ff_effect *e2)
  54{
  55        return e1->type == e2->type &&
  56               (e1->type != FF_PERIODIC ||
  57                e1->u.periodic.waveform == e2->u.periodic.waveform);
  58}
  59
  60/*
  61 * Convert an effect into compatible one
  62 */
  63static int compat_effect(struct ff_device *ff, struct ff_effect *effect)
  64{
  65        int magnitude;
  66
  67        switch (effect->type) {
  68        case FF_RUMBLE:
  69                if (!test_bit(FF_PERIODIC, ff->ffbit))
  70                        return -EINVAL;
  71
  72                /*
  73                 * calculate magnitude of sine wave as average of rumble's
  74                 * 2/3 of strong magnitude and 1/3 of weak magnitude
  75                 */
  76                magnitude = effect->u.rumble.strong_magnitude / 3 +
  77                            effect->u.rumble.weak_magnitude / 6;
  78
  79                effect->type = FF_PERIODIC;
  80                effect->u.periodic.waveform = FF_SINE;
  81                effect->u.periodic.period = 50;
  82                effect->u.periodic.magnitude = max(magnitude, 0x7fff);
  83                effect->u.periodic.offset = 0;
  84                effect->u.periodic.phase = 0;
  85                effect->u.periodic.envelope.attack_length = 0;
  86                effect->u.periodic.envelope.attack_level = 0;
  87                effect->u.periodic.envelope.fade_length = 0;
  88                effect->u.periodic.envelope.fade_level = 0;
  89
  90                return 0;
  91
  92        default:
  93                /* Let driver handle conversion */
  94                return 0;
  95        }
  96}
  97
  98/**
  99 * input_ff_upload() - upload effect into force-feedback device
 100 * @dev: input device
 101 * @effect: effect to be uploaded
 102 * @file: owner of the effect
 103 */
 104int input_ff_upload(struct input_dev *dev, struct ff_effect *effect,
 105                    struct file *file)
 106{
 107        struct ff_device *ff = dev->ff;
 108        struct ff_effect *old;
 109        int ret = 0;
 110        int id;
 111
 112        if (!test_bit(EV_FF, dev->evbit))
 113                return -ENOSYS;
 114
 115        if (effect->type < FF_EFFECT_MIN || effect->type > FF_EFFECT_MAX ||
 116            !test_bit(effect->type, dev->ffbit)) {
 117                dev_dbg(&dev->dev, "invalid or not supported effect type in upload\n");
 118                return -EINVAL;
 119        }
 120
 121        if (effect->type == FF_PERIODIC &&
 122            (effect->u.periodic.waveform < FF_WAVEFORM_MIN ||
 123             effect->u.periodic.waveform > FF_WAVEFORM_MAX ||
 124             !test_bit(effect->u.periodic.waveform, dev->ffbit))) {
 125                dev_dbg(&dev->dev, "invalid or not supported wave form in upload\n");
 126                return -EINVAL;
 127        }
 128
 129        if (!test_bit(effect->type, ff->ffbit)) {
 130                ret = compat_effect(ff, effect);
 131                if (ret)
 132                        return ret;
 133        }
 134
 135        mutex_lock(&ff->mutex);
 136
 137        if (effect->id == -1) {
 138                for (id = 0; id < ff->max_effects; id++)
 139                        if (!ff->effect_owners[id])
 140                                break;
 141
 142                if (id >= ff->max_effects) {
 143                        ret = -ENOSPC;
 144                        goto out;
 145                }
 146
 147                effect->id = id;
 148                old = NULL;
 149
 150        } else {
 151                id = effect->id;
 152
 153                ret = check_effect_access(ff, id, file);
 154                if (ret)
 155                        goto out;
 156
 157                old = &ff->effects[id];
 158
 159                if (!check_effects_compatible(effect, old)) {
 160                        ret = -EINVAL;
 161                        goto out;
 162                }
 163        }
 164
 165        ret = ff->upload(dev, effect, old);
 166        if (ret)
 167                goto out;
 168
 169        spin_lock_irq(&dev->event_lock);
 170        ff->effects[id] = *effect;
 171        ff->effect_owners[id] = file;
 172        spin_unlock_irq(&dev->event_lock);
 173
 174 out:
 175        mutex_unlock(&ff->mutex);
 176        return ret;
 177}
 178EXPORT_SYMBOL_GPL(input_ff_upload);
 179
 180/*
 181 * Erases the effect if the requester is also the effect owner. The mutex
 182 * should already be locked before calling this function.
 183 */
 184static int erase_effect(struct input_dev *dev, int effect_id,
 185                        struct file *file)
 186{
 187        struct ff_device *ff = dev->ff;
 188        int error;
 189
 190        error = check_effect_access(ff, effect_id, file);
 191        if (error)
 192                return error;
 193
 194        spin_lock_irq(&dev->event_lock);
 195        ff->playback(dev, effect_id, 0);
 196        ff->effect_owners[effect_id] = NULL;
 197        spin_unlock_irq(&dev->event_lock);
 198
 199        if (ff->erase) {
 200                error = ff->erase(dev, effect_id);
 201                if (error) {
 202                        spin_lock_irq(&dev->event_lock);
 203                        ff->effect_owners[effect_id] = file;
 204                        spin_unlock_irq(&dev->event_lock);
 205
 206                        return error;
 207                }
 208        }
 209
 210        return 0;
 211}
 212
 213/**
 214 * input_ff_erase - erase a force-feedback effect from device
 215 * @dev: input device to erase effect from
 216 * @effect_id: id of the effect to be erased
 217 * @file: purported owner of the request
 218 *
 219 * This function erases a force-feedback effect from specified device.
 220 * The effect will only be erased if it was uploaded through the same
 221 * file handle that is requesting erase.
 222 */
 223int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file)
 224{
 225        struct ff_device *ff = dev->ff;
 226        int ret;
 227
 228        if (!test_bit(EV_FF, dev->evbit))
 229                return -ENOSYS;
 230
 231        mutex_lock(&ff->mutex);
 232        ret = erase_effect(dev, effect_id, file);
 233        mutex_unlock(&ff->mutex);
 234
 235        return ret;
 236}
 237EXPORT_SYMBOL_GPL(input_ff_erase);
 238
 239/*
 240 * flush_effects - erase all effects owned by a file handle
 241 */
 242static int flush_effects(struct input_dev *dev, struct file *file)
 243{
 244        struct ff_device *ff = dev->ff;
 245        int i;
 246
 247        dev_dbg(&dev->dev, "flushing now\n");
 248
 249        mutex_lock(&ff->mutex);
 250
 251        for (i = 0; i < ff->max_effects; i++)
 252                erase_effect(dev, i, file);
 253
 254        mutex_unlock(&ff->mutex);
 255
 256        return 0;
 257}
 258
 259/**
 260 * input_ff_event() - generic handler for force-feedback events
 261 * @dev: input device to send the effect to
 262 * @type: event type (anything but EV_FF is ignored)
 263 * @code: event code
 264 * @value: event value
 265 */
 266int input_ff_event(struct input_dev *dev, unsigned int type,
 267                   unsigned int code, int value)
 268{
 269        struct ff_device *ff = dev->ff;
 270
 271        if (type != EV_FF)
 272                return 0;
 273
 274        switch (code) {
 275        case FF_GAIN:
 276                if (!test_bit(FF_GAIN, dev->ffbit) || value > 0xffffU)
 277                        break;
 278
 279                ff->set_gain(dev, value);
 280                break;
 281
 282        case FF_AUTOCENTER:
 283                if (!test_bit(FF_AUTOCENTER, dev->ffbit) || value > 0xffffU)
 284                        break;
 285
 286                ff->set_autocenter(dev, value);
 287                break;
 288
 289        default:
 290                if (check_effect_access(ff, code, NULL) == 0)
 291                        ff->playback(dev, code, value);
 292                break;
 293        }
 294
 295        return 0;
 296}
 297EXPORT_SYMBOL_GPL(input_ff_event);
 298
 299/**
 300 * input_ff_create() - create force-feedback device
 301 * @dev: input device supporting force-feedback
 302 * @max_effects: maximum number of effects supported by the device
 303 *
 304 * This function allocates all necessary memory for a force feedback
 305 * portion of an input device and installs all default handlers.
 306 * @dev->ffbit should be already set up before calling this function.
 307 * Once ff device is created you need to setup its upload, erase,
 308 * playback and other handlers before registering input device
 309 */
 310int input_ff_create(struct input_dev *dev, unsigned int max_effects)
 311{
 312        struct ff_device *ff;
 313        size_t ff_dev_size;
 314        int i;
 315
 316        if (!max_effects) {
 317                dev_err(&dev->dev, "cannot allocate device without any effects\n");
 318                return -EINVAL;
 319        }
 320
 321        if (max_effects > FF_MAX_EFFECTS) {
 322                dev_err(&dev->dev, "cannot allocate more than FF_MAX_EFFECTS effects\n");
 323                return -EINVAL;
 324        }
 325
 326        ff_dev_size = sizeof(struct ff_device) +
 327                                max_effects * sizeof(struct file *);
 328        if (ff_dev_size < max_effects) /* overflow */
 329                return -EINVAL;
 330
 331        ff = kzalloc(ff_dev_size, GFP_KERNEL);
 332        if (!ff)
 333                return -ENOMEM;
 334
 335        ff->effects = kcalloc(max_effects, sizeof(struct ff_effect),
 336                              GFP_KERNEL);
 337        if (!ff->effects) {
 338                kfree(ff);
 339                return -ENOMEM;
 340        }
 341
 342        ff->max_effects = max_effects;
 343        mutex_init(&ff->mutex);
 344
 345        dev->ff = ff;
 346        dev->flush = flush_effects;
 347        dev->event = input_ff_event;
 348        __set_bit(EV_FF, dev->evbit);
 349
 350        /* Copy "true" bits into ff device bitmap */
 351        for_each_set_bit(i, dev->ffbit, FF_CNT)
 352                __set_bit(i, ff->ffbit);
 353
 354        /* we can emulate RUMBLE with periodic effects */
 355        if (test_bit(FF_PERIODIC, ff->ffbit))
 356                __set_bit(FF_RUMBLE, dev->ffbit);
 357
 358        return 0;
 359}
 360EXPORT_SYMBOL_GPL(input_ff_create);
 361
 362/**
 363 * input_ff_destroy() - frees force feedback portion of input device
 364 * @dev: input device supporting force feedback
 365 *
 366 * This function is only needed in error path as input core will
 367 * automatically free force feedback structures when device is
 368 * destroyed.
 369 */
 370void input_ff_destroy(struct input_dev *dev)
 371{
 372        struct ff_device *ff = dev->ff;
 373
 374        __clear_bit(EV_FF, dev->evbit);
 375        if (ff) {
 376                if (ff->destroy)
 377                        ff->destroy(ff);
 378                kfree(ff->private);
 379                kfree(ff->effects);
 380                kfree(ff);
 381                dev->ff = NULL;
 382        }
 383}
 384EXPORT_SYMBOL_GPL(input_ff_destroy);
 385