diff options
author | Jari Vanhala <ext-jari.vanhala@nokia.com> | 2009-12-25 06:52:20 +0100 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-12-25 06:54:29 +0100 |
commit | 94ec26c855bc675259e4f1658673f458040affd7 (patch) | |
tree | a5af53ce488e6f0b8e5ca521ebc861a96ed1ffa8 /drivers/input/ff-memless.c | |
parent | Input: ff-memless - another fix for signed to unsigned overflow (diff) | |
download | linux-94ec26c855bc675259e4f1658673f458040affd7.tar.xz linux-94ec26c855bc675259e4f1658673f458040affd7.zip |
Input: ff-memless - add notion of direction to for rumble effects
This adds simple direction calculation when combining effects. It's useful
to decide motor direction for rumble (vibrator).
Signed-off-by: Jari Vanhala <ext-jari.vanhala@nokia.com>
Acked-by: Anssi Hannula <anssi.hannula@iki.fi>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/ff-memless.c')
-rw-r--r-- | drivers/input/ff-memless.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index 9667a5fd6bd7..f967008f332e 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -221,6 +221,22 @@ 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, @@ -254,6 +270,19 @@ static void ml_combine_effects(struct ff_effect *effect, case FF_RUMBLE: 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 = |