Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Force feedback support for Linux input subsystem
0004  *
0005  *  Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>
0006  *  Copyright (c) 2006 Dmitry Torokhov <dtor@mail.ru>
0007  */
0008 
0009 /*
0010  */
0011 
0012 /* #define DEBUG */
0013 
0014 #include <linux/input.h>
0015 #include <linux/module.h>
0016 #include <linux/mutex.h>
0017 #include <linux/sched.h>
0018 #include <linux/slab.h>
0019 
0020 /*
0021  * Check that the effect_id is a valid effect and whether the user
0022  * is the owner
0023  */
0024 static int check_effect_access(struct ff_device *ff, int effect_id,
0025                 struct file *file)
0026 {
0027     if (effect_id < 0 || effect_id >= ff->max_effects ||
0028         !ff->effect_owners[effect_id])
0029         return -EINVAL;
0030 
0031     if (file && ff->effect_owners[effect_id] != file)
0032         return -EACCES;
0033 
0034     return 0;
0035 }
0036 
0037 /*
0038  * Checks whether 2 effects can be combined together
0039  */
0040 static inline int check_effects_compatible(struct ff_effect *e1,
0041                        struct ff_effect *e2)
0042 {
0043     return e1->type == e2->type &&
0044            (e1->type != FF_PERIODIC ||
0045         e1->u.periodic.waveform == e2->u.periodic.waveform);
0046 }
0047 
0048 /*
0049  * Convert an effect into compatible one
0050  */
0051 static int compat_effect(struct ff_device *ff, struct ff_effect *effect)
0052 {
0053     int magnitude;
0054 
0055     switch (effect->type) {
0056     case FF_RUMBLE:
0057         if (!test_bit(FF_PERIODIC, ff->ffbit))
0058             return -EINVAL;
0059 
0060         /*
0061          * calculate magnitude of sine wave as average of rumble's
0062          * 2/3 of strong magnitude and 1/3 of weak magnitude
0063          */
0064         magnitude = effect->u.rumble.strong_magnitude / 3 +
0065                 effect->u.rumble.weak_magnitude / 6;
0066 
0067         effect->type = FF_PERIODIC;
0068         effect->u.periodic.waveform = FF_SINE;
0069         effect->u.periodic.period = 50;
0070         effect->u.periodic.magnitude = magnitude;
0071         effect->u.periodic.offset = 0;
0072         effect->u.periodic.phase = 0;
0073         effect->u.periodic.envelope.attack_length = 0;
0074         effect->u.periodic.envelope.attack_level = 0;
0075         effect->u.periodic.envelope.fade_length = 0;
0076         effect->u.periodic.envelope.fade_level = 0;
0077 
0078         return 0;
0079 
0080     default:
0081         /* Let driver handle conversion */
0082         return 0;
0083     }
0084 }
0085 
0086 /**
0087  * input_ff_upload() - upload effect into force-feedback device
0088  * @dev: input device
0089  * @effect: effect to be uploaded
0090  * @file: owner of the effect
0091  */
0092 int input_ff_upload(struct input_dev *dev, struct ff_effect *effect,
0093             struct file *file)
0094 {
0095     struct ff_device *ff = dev->ff;
0096     struct ff_effect *old;
0097     int ret = 0;
0098     int id;
0099 
0100     if (!test_bit(EV_FF, dev->evbit))
0101         return -ENOSYS;
0102 
0103     if (effect->type < FF_EFFECT_MIN || effect->type > FF_EFFECT_MAX ||
0104         !test_bit(effect->type, dev->ffbit)) {
0105         dev_dbg(&dev->dev, "invalid or not supported effect type in upload\n");
0106         return -EINVAL;
0107     }
0108 
0109     if (effect->type == FF_PERIODIC &&
0110         (effect->u.periodic.waveform < FF_WAVEFORM_MIN ||
0111          effect->u.periodic.waveform > FF_WAVEFORM_MAX ||
0112          !test_bit(effect->u.periodic.waveform, dev->ffbit))) {
0113         dev_dbg(&dev->dev, "invalid or not supported wave form in upload\n");
0114         return -EINVAL;
0115     }
0116 
0117     if (!test_bit(effect->type, ff->ffbit)) {
0118         ret = compat_effect(ff, effect);
0119         if (ret)
0120             return ret;
0121     }
0122 
0123     mutex_lock(&ff->mutex);
0124 
0125     if (effect->id == -1) {
0126         for (id = 0; id < ff->max_effects; id++)
0127             if (!ff->effect_owners[id])
0128                 break;
0129 
0130         if (id >= ff->max_effects) {
0131             ret = -ENOSPC;
0132             goto out;
0133         }
0134 
0135         effect->id = id;
0136         old = NULL;
0137 
0138     } else {
0139         id = effect->id;
0140 
0141         ret = check_effect_access(ff, id, file);
0142         if (ret)
0143             goto out;
0144 
0145         old = &ff->effects[id];
0146 
0147         if (!check_effects_compatible(effect, old)) {
0148             ret = -EINVAL;
0149             goto out;
0150         }
0151     }
0152 
0153     ret = ff->upload(dev, effect, old);
0154     if (ret)
0155         goto out;
0156 
0157     spin_lock_irq(&dev->event_lock);
0158     ff->effects[id] = *effect;
0159     ff->effect_owners[id] = file;
0160     spin_unlock_irq(&dev->event_lock);
0161 
0162  out:
0163     mutex_unlock(&ff->mutex);
0164     return ret;
0165 }
0166 EXPORT_SYMBOL_GPL(input_ff_upload);
0167 
0168 /*
0169  * Erases the effect if the requester is also the effect owner. The mutex
0170  * should already be locked before calling this function.
0171  */
0172 static int erase_effect(struct input_dev *dev, int effect_id,
0173             struct file *file)
0174 {
0175     struct ff_device *ff = dev->ff;
0176     int error;
0177 
0178     error = check_effect_access(ff, effect_id, file);
0179     if (error)
0180         return error;
0181 
0182     spin_lock_irq(&dev->event_lock);
0183     ff->playback(dev, effect_id, 0);
0184     ff->effect_owners[effect_id] = NULL;
0185     spin_unlock_irq(&dev->event_lock);
0186 
0187     if (ff->erase) {
0188         error = ff->erase(dev, effect_id);
0189         if (error) {
0190             spin_lock_irq(&dev->event_lock);
0191             ff->effect_owners[effect_id] = file;
0192             spin_unlock_irq(&dev->event_lock);
0193 
0194             return error;
0195         }
0196     }
0197 
0198     return 0;
0199 }
0200 
0201 /**
0202  * input_ff_erase - erase a force-feedback effect from device
0203  * @dev: input device to erase effect from
0204  * @effect_id: id of the effect to be erased
0205  * @file: purported owner of the request
0206  *
0207  * This function erases a force-feedback effect from specified device.
0208  * The effect will only be erased if it was uploaded through the same
0209  * file handle that is requesting erase.
0210  */
0211 int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file)
0212 {
0213     struct ff_device *ff = dev->ff;
0214     int ret;
0215 
0216     if (!test_bit(EV_FF, dev->evbit))
0217         return -ENOSYS;
0218 
0219     mutex_lock(&ff->mutex);
0220     ret = erase_effect(dev, effect_id, file);
0221     mutex_unlock(&ff->mutex);
0222 
0223     return ret;
0224 }
0225 EXPORT_SYMBOL_GPL(input_ff_erase);
0226 
0227 /*
0228  * input_ff_flush - erase all effects owned by a file handle
0229  * @dev: input device to erase effect from
0230  * @file: purported owner of the effects
0231  *
0232  * This function erases all force-feedback effects associated with
0233  * the given owner from specified device. Note that @file may be %NULL,
0234  * in which case all effects will be erased.
0235  */
0236 int input_ff_flush(struct input_dev *dev, struct file *file)
0237 {
0238     struct ff_device *ff = dev->ff;
0239     int i;
0240 
0241     dev_dbg(&dev->dev, "flushing now\n");
0242 
0243     mutex_lock(&ff->mutex);
0244 
0245     for (i = 0; i < ff->max_effects; i++)
0246         erase_effect(dev, i, file);
0247 
0248     mutex_unlock(&ff->mutex);
0249 
0250     return 0;
0251 }
0252 EXPORT_SYMBOL_GPL(input_ff_flush);
0253 
0254 /**
0255  * input_ff_event() - generic handler for force-feedback events
0256  * @dev: input device to send the effect to
0257  * @type: event type (anything but EV_FF is ignored)
0258  * @code: event code
0259  * @value: event value
0260  */
0261 int input_ff_event(struct input_dev *dev, unsigned int type,
0262            unsigned int code, int value)
0263 {
0264     struct ff_device *ff = dev->ff;
0265 
0266     if (type != EV_FF)
0267         return 0;
0268 
0269     switch (code) {
0270     case FF_GAIN:
0271         if (!test_bit(FF_GAIN, dev->ffbit) || value > 0xffffU)
0272             break;
0273 
0274         ff->set_gain(dev, value);
0275         break;
0276 
0277     case FF_AUTOCENTER:
0278         if (!test_bit(FF_AUTOCENTER, dev->ffbit) || value > 0xffffU)
0279             break;
0280 
0281         ff->set_autocenter(dev, value);
0282         break;
0283 
0284     default:
0285         if (check_effect_access(ff, code, NULL) == 0)
0286             ff->playback(dev, code, value);
0287         break;
0288     }
0289 
0290     return 0;
0291 }
0292 EXPORT_SYMBOL_GPL(input_ff_event);
0293 
0294 /**
0295  * input_ff_create() - create force-feedback device
0296  * @dev: input device supporting force-feedback
0297  * @max_effects: maximum number of effects supported by the device
0298  *
0299  * This function allocates all necessary memory for a force feedback
0300  * portion of an input device and installs all default handlers.
0301  * @dev->ffbit should be already set up before calling this function.
0302  * Once ff device is created you need to setup its upload, erase,
0303  * playback and other handlers before registering input device
0304  */
0305 int input_ff_create(struct input_dev *dev, unsigned int max_effects)
0306 {
0307     struct ff_device *ff;
0308     size_t ff_dev_size;
0309     int i;
0310 
0311     if (!max_effects) {
0312         dev_err(&dev->dev, "cannot allocate device without any effects\n");
0313         return -EINVAL;
0314     }
0315 
0316     if (max_effects > FF_MAX_EFFECTS) {
0317         dev_err(&dev->dev, "cannot allocate more than FF_MAX_EFFECTS effects\n");
0318         return -EINVAL;
0319     }
0320 
0321     ff_dev_size = sizeof(struct ff_device) +
0322                 max_effects * sizeof(struct file *);
0323     if (ff_dev_size < max_effects) /* overflow */
0324         return -EINVAL;
0325 
0326     ff = kzalloc(ff_dev_size, GFP_KERNEL);
0327     if (!ff)
0328         return -ENOMEM;
0329 
0330     ff->effects = kcalloc(max_effects, sizeof(struct ff_effect),
0331                   GFP_KERNEL);
0332     if (!ff->effects) {
0333         kfree(ff);
0334         return -ENOMEM;
0335     }
0336 
0337     ff->max_effects = max_effects;
0338     mutex_init(&ff->mutex);
0339 
0340     dev->ff = ff;
0341     dev->flush = input_ff_flush;
0342     dev->event = input_ff_event;
0343     __set_bit(EV_FF, dev->evbit);
0344 
0345     /* Copy "true" bits into ff device bitmap */
0346     for_each_set_bit(i, dev->ffbit, FF_CNT)
0347         __set_bit(i, ff->ffbit);
0348 
0349     /* we can emulate RUMBLE with periodic effects */
0350     if (test_bit(FF_PERIODIC, ff->ffbit))
0351         __set_bit(FF_RUMBLE, dev->ffbit);
0352 
0353     return 0;
0354 }
0355 EXPORT_SYMBOL_GPL(input_ff_create);
0356 
0357 /**
0358  * input_ff_destroy() - frees force feedback portion of input device
0359  * @dev: input device supporting force feedback
0360  *
0361  * This function is only needed in error path as input core will
0362  * automatically free force feedback structures when device is
0363  * destroyed.
0364  */
0365 void input_ff_destroy(struct input_dev *dev)
0366 {
0367     struct ff_device *ff = dev->ff;
0368 
0369     __clear_bit(EV_FF, dev->evbit);
0370     if (ff) {
0371         if (ff->destroy)
0372             ff->destroy(ff);
0373         kfree(ff->private);
0374         kfree(ff->effects);
0375         kfree(ff);
0376         dev->ff = NULL;
0377     }
0378 }
0379 EXPORT_SYMBOL_GPL(input_ff_destroy);