root/drivers/input/ff-core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. check_effect_access
  2. check_effects_compatible
  3. compat_effect
  4. input_ff_upload
  5. erase_effect
  6. input_ff_erase
  7. input_ff_flush
  8. input_ff_event
  9. input_ff_create
  10. input_ff_destroy

   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  */
  24 static 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  */
  40 static 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  */
  51 static 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  */
  92 int 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 }
 166 EXPORT_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  */
 172 static 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  */
 211 int 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 }
 225 EXPORT_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  */
 236 int 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 }
 252 EXPORT_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  */
 261 int 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 }
 292 EXPORT_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  */
 305 int 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 }
 355 EXPORT_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  */
 365 void 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 }
 379 EXPORT_SYMBOL_GPL(input_ff_destroy);

/* [<][>][^][v][top][bottom][index][help] */