diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-31 11:12:35 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-31 11:12:35 -0800 |
commit | 4e58fb7305449cf8c5a86dd97dfc1812221be77c (patch) | |
tree | 6cc0bf0089fdde87ea2e082c6193ea3ab2fe2131 /drivers/input/ff-memless.c | |
parent | 08d869aa8683703c4a60fdc574dd0809f9b073cd (diff) | |
parent | c2b27ef672992a206e5b221b8676972dd840ffa5 (diff) | |
download | linux-rt-4e58fb7305449cf8c5a86dd97dfc1812221be77c.tar.gz |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: iforce - wait for command completion when closing the device
Input: twl4030-pwrbutton - switch to using threaded IRQ
Input: twl4030_keypad - switch to using threaded IRQ
Input: lifebook - add CONFIG_DMI dependency
Input: wistron - fix test for CONFIG_PM
Input: psmouse - fix compile warning in hgpk module
Input: matrix-keypad - handle cases when GPIOs can't be wakeup sources
Input: iforce - fix oops on device disconnect
Input: ff-memless - add notion of direction to for rumble effects
Input: ff-memless - another fix for signed to unsigned overflow
Input: ff-memless - start playing FF effects immediately
Input: serio - do not mark kseriod freezable anymore
Input: speed up suspend/shutdown for PS/2 mice and keyboards
Diffstat (limited to 'drivers/input/ff-memless.c')
-rw-r--r-- | drivers/input/ff-memless.c | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index b483b2995fa9..f967008f332e 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -221,11 +221,27 @@ static int get_compatible_type(struct ff_device *ff, int effect_type) } /* + * Only left/right direction should be used (under/over 0x8000) for + * forward/reverse motor direction (to keep calculation fast & simple). + */ +static u16 ml_calculate_direction(u16 direction, u16 force, + u16 new_direction, u16 new_force) +{ + if (!force) + return new_direction; + if (!new_force) + return direction; + return (((u32)(direction >> 1) * force + + (new_direction >> 1) * new_force) / + (force + new_force)) << 1; +} + +/* * Combine two effects and apply gain. */ static void ml_combine_effects(struct ff_effect *effect, struct ml_effect_state *state, - unsigned int gain) + int gain) { struct ff_effect *new = state->effect; unsigned int strong, weak, i; @@ -252,8 +268,21 @@ static void ml_combine_effects(struct ff_effect *effect, break; case FF_RUMBLE: - strong = new->u.rumble.strong_magnitude * gain / 0xffff; - weak = new->u.rumble.weak_magnitude * gain / 0xffff; + strong = (u32)new->u.rumble.strong_magnitude * gain / 0xffff; + weak = (u32)new->u.rumble.weak_magnitude * gain / 0xffff; + + if (effect->u.rumble.strong_magnitude + strong) + effect->direction = ml_calculate_direction( + effect->direction, + effect->u.rumble.strong_magnitude, + new->direction, strong); + else if (effect->u.rumble.weak_magnitude + weak) + effect->direction = ml_calculate_direction( + effect->direction, + effect->u.rumble.weak_magnitude, + new->direction, weak); + else + effect->direction = 0; effect->u.rumble.strong_magnitude = min(strong + effect->u.rumble.strong_magnitude, 0xffffU); @@ -268,6 +297,13 @@ static void ml_combine_effects(struct ff_effect *effect, /* here we also scale it 0x7fff => 0xffff */ i = i * gain / 0x7fff; + if (effect->u.rumble.strong_magnitude + i) + effect->direction = ml_calculate_direction( + effect->direction, + effect->u.rumble.strong_magnitude, + new->direction, i); + else + effect->direction = 0; effect->u.rumble.strong_magnitude = min(i + effect->u.rumble.strong_magnitude, 0xffffU); effect->u.rumble.weak_magnitude = @@ -411,8 +447,6 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value) msecs_to_jiffies(state->effect->replay.length); state->adj_at = state->play_at; - ml_schedule_timer(ml); - } else { debug("initiated stop"); @@ -420,10 +454,10 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value) __set_bit(FF_EFFECT_ABORTING, &state->flags); else __clear_bit(FF_EFFECT_STARTED, &state->flags); - - ml_play_effects(ml); } + ml_play_effects(ml); + return 0; } |