aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/ff-memless.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/ff-memless.c')
-rw-r--r--drivers/input/ff-memless.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c
index b483b2995fa9..1d881c96ba8f 100644
--- a/drivers/input/ff-memless.c
+++ b/drivers/input/ff-memless.c
@@ -25,6 +25,7 @@
25 25
26#define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg) 26#define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg)
27 27
28#include <linux/slab.h>
28#include <linux/input.h> 29#include <linux/input.h>
29#include <linux/module.h> 30#include <linux/module.h>
30#include <linux/mutex.h> 31#include <linux/mutex.h>
@@ -221,11 +222,27 @@ static int get_compatible_type(struct ff_device *ff, int effect_type)
221} 222}
222 223
223/* 224/*
225 * Only left/right direction should be used (under/over 0x8000) for
226 * forward/reverse motor direction (to keep calculation fast & simple).
227 */
228static u16 ml_calculate_direction(u16 direction, u16 force,
229 u16 new_direction, u16 new_force)
230{
231 if (!force)
232 return new_direction;
233 if (!new_force)
234 return direction;
235 return (((u32)(direction >> 1) * force +
236 (new_direction >> 1) * new_force) /
237 (force + new_force)) << 1;
238}
239
240/*
224 * Combine two effects and apply gain. 241 * Combine two effects and apply gain.
225 */ 242 */
226static void ml_combine_effects(struct ff_effect *effect, 243static void ml_combine_effects(struct ff_effect *effect,
227 struct ml_effect_state *state, 244 struct ml_effect_state *state,
228 unsigned int gain) 245 int gain)
229{ 246{
230 struct ff_effect *new = state->effect; 247 struct ff_effect *new = state->effect;
231 unsigned int strong, weak, i; 248 unsigned int strong, weak, i;
@@ -252,8 +269,21 @@ static void ml_combine_effects(struct ff_effect *effect,
252 break; 269 break;
253 270
254 case FF_RUMBLE: 271 case FF_RUMBLE:
255 strong = new->u.rumble.strong_magnitude * gain / 0xffff; 272 strong = (u32)new->u.rumble.strong_magnitude * gain / 0xffff;
256 weak = new->u.rumble.weak_magnitude * gain / 0xffff; 273 weak = (u32)new->u.rumble.weak_magnitude * gain / 0xffff;
274
275 if (effect->u.rumble.strong_magnitude + strong)
276 effect->direction = ml_calculate_direction(
277 effect->direction,
278 effect->u.rumble.strong_magnitude,
279 new->direction, strong);
280 else if (effect->u.rumble.weak_magnitude + weak)
281 effect->direction = ml_calculate_direction(
282 effect->direction,
283 effect->u.rumble.weak_magnitude,
284 new->direction, weak);
285 else
286 effect->direction = 0;
257 effect->u.rumble.strong_magnitude = 287 effect->u.rumble.strong_magnitude =
258 min(strong + effect->u.rumble.strong_magnitude, 288 min(strong + effect->u.rumble.strong_magnitude,
259 0xffffU); 289 0xffffU);
@@ -268,6 +298,13 @@ static void ml_combine_effects(struct ff_effect *effect,
268 /* here we also scale it 0x7fff => 0xffff */ 298 /* here we also scale it 0x7fff => 0xffff */
269 i = i * gain / 0x7fff; 299 i = i * gain / 0x7fff;
270 300
301 if (effect->u.rumble.strong_magnitude + i)
302 effect->direction = ml_calculate_direction(
303 effect->direction,
304 effect->u.rumble.strong_magnitude,
305 new->direction, i);
306 else
307 effect->direction = 0;
271 effect->u.rumble.strong_magnitude = 308 effect->u.rumble.strong_magnitude =
272 min(i + effect->u.rumble.strong_magnitude, 0xffffU); 309 min(i + effect->u.rumble.strong_magnitude, 0xffffU);
273 effect->u.rumble.weak_magnitude = 310 effect->u.rumble.weak_magnitude =
@@ -411,8 +448,6 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
411 msecs_to_jiffies(state->effect->replay.length); 448 msecs_to_jiffies(state->effect->replay.length);
412 state->adj_at = state->play_at; 449 state->adj_at = state->play_at;
413 450
414 ml_schedule_timer(ml);
415
416 } else { 451 } else {
417 debug("initiated stop"); 452 debug("initiated stop");
418 453
@@ -420,10 +455,10 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
420 __set_bit(FF_EFFECT_ABORTING, &state->flags); 455 __set_bit(FF_EFFECT_ABORTING, &state->flags);
421 else 456 else
422 __clear_bit(FF_EFFECT_STARTED, &state->flags); 457 __clear_bit(FF_EFFECT_STARTED, &state->flags);
423
424 ml_play_effects(ml);
425 } 458 }
426 459
460 ml_play_effects(ml);
461
427 return 0; 462 return 0;
428} 463}
429 464