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