LCOV - code coverage report
Current view: top level - drivers/input - ff-core.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 10 164 6.1 %
Date: 2017-01-25 Functions: 1 10 10.0 %

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

Generated by: LCOV version 1.10