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