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