Branch data Line data Source code
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 : 0 : if (effect_id < 0 || effect_id >= ff->max_effects || 28 : 0 : !ff->effect_owners[effect_id]) 29 : : return -EINVAL; 30 : : 31 : 0 : 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 : 0 : return e1->type == e2->type && 44 : 0 : (e1->type != FF_PERIODIC || 45 : 0 : e1->u.periodic.waveform == e2->u.periodic.waveform); 46 : : } 47 : : 48 : : /* 49 : : * Convert an effect into compatible one 50 : : */ 51 : 0 : static int compat_effect(struct ff_device *ff, struct ff_effect *effect) 52 : : { 53 : : int magnitude; 54 : : 55 : 0 : switch (effect->type) { 56 : : case FF_RUMBLE: 57 : 0 : 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 : 0 : magnitude = effect->u.rumble.strong_magnitude / 3 + 65 : 0 : effect->u.rumble.weak_magnitude / 6; 66 : : 67 : 0 : effect->type = FF_PERIODIC; 68 : 0 : effect->u.periodic.waveform = FF_SINE; 69 : 0 : effect->u.periodic.period = 50; 70 : 0 : effect->u.periodic.magnitude = max(magnitude, 0x7fff); 71 : 0 : effect->u.periodic.offset = 0; 72 : 0 : effect->u.periodic.phase = 0; 73 : 0 : effect->u.periodic.envelope.attack_length = 0; 74 : 0 : effect->u.periodic.envelope.attack_level = 0; 75 : 0 : effect->u.periodic.envelope.fade_length = 0; 76 : 0 : effect->u.periodic.envelope.fade_level = 0; 77 : : 78 : 0 : 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 : 0 : int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, 93 : : struct file *file) 94 : : { 95 : 0 : struct ff_device *ff = dev->ff; 96 : : struct ff_effect *old; 97 : : int ret = 0; 98 : : int id; 99 : : 100 : 0 : if (!test_bit(EV_FF, dev->evbit)) 101 : : return -ENOSYS; 102 : : 103 : 0 : if (effect->type < FF_EFFECT_MIN || effect->type > FF_EFFECT_MAX || 104 : 0 : !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 : 0 : if (effect->type == FF_PERIODIC && 110 : 0 : (effect->u.periodic.waveform < FF_WAVEFORM_MIN || 111 : 0 : effect->u.periodic.waveform > FF_WAVEFORM_MAX || 112 : 0 : !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 : 0 : if (!test_bit(effect->type, ff->ffbit)) { 118 : 0 : ret = compat_effect(ff, effect); 119 : 0 : if (ret) 120 : : return ret; 121 : : } 122 : : 123 : 0 : mutex_lock(&ff->mutex); 124 : : 125 : 0 : if (effect->id == -1) { 126 : 0 : for (id = 0; id < ff->max_effects; id++) 127 : 0 : if (!ff->effect_owners[id]) 128 : : break; 129 : : 130 : 0 : if (id >= ff->max_effects) { 131 : : ret = -ENOSPC; 132 : : goto out; 133 : : } 134 : : 135 : 0 : effect->id = id; 136 : : old = NULL; 137 : : 138 : : } else { 139 : 0 : id = effect->id; 140 : : 141 : : ret = check_effect_access(ff, id, file); 142 : 0 : if (ret) 143 : : goto out; 144 : : 145 : 0 : old = &ff->effects[id]; 146 : : 147 : 0 : if (!check_effects_compatible(effect, old)) { 148 : : ret = -EINVAL; 149 : : goto out; 150 : : } 151 : : } 152 : : 153 : 0 : ret = ff->upload(dev, effect, old); 154 : 0 : if (ret) 155 : : goto out; 156 : : 157 : : spin_lock_irq(&dev->event_lock); 158 : 0 : ff->effects[id] = *effect; 159 : 0 : ff->effect_owners[id] = file; 160 : : spin_unlock_irq(&dev->event_lock); 161 : : 162 : : out: 163 : 0 : mutex_unlock(&ff->mutex); 164 : 0 : 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 : 0 : static int erase_effect(struct input_dev *dev, int effect_id, 173 : : struct file *file) 174 : : { 175 : 0 : struct ff_device *ff = dev->ff; 176 : : int error; 177 : : 178 : : error = check_effect_access(ff, effect_id, file); 179 : 0 : if (error) 180 : : return error; 181 : : 182 : : spin_lock_irq(&dev->event_lock); 183 : 0 : ff->playback(dev, effect_id, 0); 184 : 0 : ff->effect_owners[effect_id] = NULL; 185 : : spin_unlock_irq(&dev->event_lock); 186 : : 187 : 0 : if (ff->erase) { 188 : 0 : error = ff->erase(dev, effect_id); 189 : 0 : if (error) { 190 : : spin_lock_irq(&dev->event_lock); 191 : 0 : ff->effect_owners[effect_id] = file; 192 : : spin_unlock_irq(&dev->event_lock); 193 : : 194 : 0 : 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 : 0 : int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file) 212 : : { 213 : 0 : struct ff_device *ff = dev->ff; 214 : : int ret; 215 : : 216 : 0 : if (!test_bit(EV_FF, dev->evbit)) 217 : : return -ENOSYS; 218 : : 219 : 0 : mutex_lock(&ff->mutex); 220 : 0 : ret = erase_effect(dev, effect_id, file); 221 : 0 : mutex_unlock(&ff->mutex); 222 : : 223 : 0 : 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 : 0 : int input_ff_flush(struct input_dev *dev, struct file *file) 237 : : { 238 : 0 : struct ff_device *ff = dev->ff; 239 : : int i; 240 : : 241 : : dev_dbg(&dev->dev, "flushing now\n"); 242 : : 243 : 0 : mutex_lock(&ff->mutex); 244 : : 245 : 0 : for (i = 0; i < ff->max_effects; i++) 246 : 0 : erase_effect(dev, i, file); 247 : : 248 : 0 : mutex_unlock(&ff->mutex); 249 : : 250 : 0 : 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 : 0 : int input_ff_event(struct input_dev *dev, unsigned int type, 262 : : unsigned int code, int value) 263 : : { 264 : 0 : struct ff_device *ff = dev->ff; 265 : : 266 : 0 : if (type != EV_FF) 267 : : return 0; 268 : : 269 : 0 : switch (code) { 270 : : case FF_GAIN: 271 : 0 : if (!test_bit(FF_GAIN, dev->ffbit) || value > 0xffffU) 272 : : break; 273 : : 274 : 0 : ff->set_gain(dev, value); 275 : 0 : break; 276 : : 277 : : case FF_AUTOCENTER: 278 : 0 : if (!test_bit(FF_AUTOCENTER, dev->ffbit) || value > 0xffffU) 279 : : break; 280 : : 281 : 0 : ff->set_autocenter(dev, value); 282 : 0 : break; 283 : : 284 : : default: 285 : 0 : if (check_effect_access(ff, code, NULL) == 0) 286 : 0 : 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 : 0 : 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 : 0 : if (!max_effects) { 312 : 0 : dev_err(&dev->dev, "cannot allocate device without any effects\n"); 313 : 0 : return -EINVAL; 314 : : } 315 : : 316 : 0 : if (max_effects > FF_MAX_EFFECTS) { 317 : 0 : dev_err(&dev->dev, "cannot allocate more than FF_MAX_EFFECTS effects\n"); 318 : 0 : return -EINVAL; 319 : : } 320 : : 321 : 0 : ff_dev_size = sizeof(struct ff_device) + 322 : : max_effects * sizeof(struct file *); 323 : 0 : if (ff_dev_size < max_effects) /* overflow */ 324 : : return -EINVAL; 325 : : 326 : 0 : ff = kzalloc(ff_dev_size, GFP_KERNEL); 327 : 0 : if (!ff) 328 : : return -ENOMEM; 329 : : 330 : 0 : ff->effects = kcalloc(max_effects, sizeof(struct ff_effect), 331 : : GFP_KERNEL); 332 : 0 : if (!ff->effects) { 333 : 0 : kfree(ff); 334 : 0 : return -ENOMEM; 335 : : } 336 : : 337 : 0 : ff->max_effects = max_effects; 338 : 0 : mutex_init(&ff->mutex); 339 : : 340 : 0 : dev->ff = ff; 341 : 0 : dev->flush = input_ff_flush; 342 : 0 : dev->event = input_ff_event; 343 : : __set_bit(EV_FF, dev->evbit); 344 : : 345 : : /* Copy "true" bits into ff device bitmap */ 346 : 0 : for_each_set_bit(i, dev->ffbit, FF_CNT) 347 : 0 : __set_bit(i, ff->ffbit); 348 : : 349 : : /* we can emulate RUMBLE with periodic effects */ 350 : 0 : 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 : 0 : void input_ff_destroy(struct input_dev *dev) 366 : : { 367 : 0 : struct ff_device *ff = dev->ff; 368 : : 369 : : __clear_bit(EV_FF, dev->evbit); 370 : 0 : if (ff) { 371 : 0 : if (ff->destroy) 372 : 0 : ff->destroy(ff); 373 : 0 : kfree(ff->private); 374 : 0 : kfree(ff->effects); 375 : 0 : kfree(ff); 376 : 0 : dev->ff = NULL; 377 : : } 378 : 0 : } 379 : : EXPORT_SYMBOL_GPL(input_ff_destroy);