@@ -810,7 +810,8 @@ static __always_inline int lg4ff_timer(struct lg4ff_device_entry *entry)
810
810
811
811
memset (parameters , 0 , sizeof (parameters ));
812
812
813
- gain = (unsigned )entry -> wdata .master_gain * entry -> wdata .gain / 0xffff ;
813
+ // Use a 8bit gain value to avoid 64bit arithmetic later
814
+ gain = ((entry -> wdata .master_gain / 0xff ) * (entry -> wdata .gain / 0xff ) + entry -> wdata .master_gain / 0xff + entry -> wdata .gain / 0xff ) / 0x100 ;
814
815
815
816
spin_lock_irqsave (& entry -> timer_lock , flags );
816
817
@@ -872,16 +873,19 @@ static __always_inline int lg4ff_timer(struct lg4ff_device_entry *entry)
872
873
873
874
spin_unlock_irqrestore (& entry -> timer_lock , flags );
874
875
875
- parameters [0 ].level = (long )parameters [0 ].level * gain / 0xffff ;
876
+ // Level might be the sum of several forces and add up to more than a
877
+ // 16bit value but less than 24bit.
878
+ // Here we avoid 64bit arithmetic by using an 8bit gain value.
879
+ parameters [0 ].level = parameters [0 ].level * gain / 0xff ;
876
880
parameters [1 ].clip = parameters [1 ].clip * spring_level / 100 ;
877
881
parameters [2 ].clip = parameters [2 ].clip * damper_level / 100 ;
878
882
parameters [3 ].clip = parameters [3 ].clip * friction_level / 100 ;
879
883
880
884
ffb_level = abs (parameters [0 ].level );
881
885
for (i = 1 ; i < 4 ; i ++ ) {
882
- parameters [i ].k1 = ( long ) parameters [i ].k1 * gain / 0xffff ;
883
- parameters [i ].k2 = ( long ) parameters [i ].k2 * gain / 0xffff ;
884
- parameters [i ].clip = parameters [i ].clip * gain / 0xffff ;
886
+ parameters [i ].k1 = parameters [i ].k1 * gain / 0xff ;
887
+ parameters [i ].k2 = parameters [i ].k2 * gain / 0xff ;
888
+ parameters [i ].clip = parameters [i ].clip * gain / 0xff ;
885
889
ffb_level += parameters [i ].clip * 0x7fff / 0xffff ;
886
890
}
887
891
if (ffb_level > entry -> peak_ffb_level ) {
0 commit comments