22
22
#define PID_EFFECTS_MAX 64
23
23
#define PID_INFINITE 0xffff
24
24
25
+ /* Linux Force Feedback API uses miliseconds as time unit */
26
+ #define FF_TIME_EXPONENT -3
27
+
25
28
/* Report usage table used to put reports into an array */
26
29
27
30
#define PID_SET_EFFECT 0
@@ -231,6 +234,24 @@ static int pidff_rescale_signed(int i, struct hid_field *field)
231
234
field -> logical_minimum / -0x8000 ;
232
235
}
233
236
237
+ /*
238
+ * Scale time value from Linux default (ms) to field units
239
+ */
240
+ static u32 pidff_rescale_time (u16 time , struct hid_field * field )
241
+ {
242
+ u32 scaled_time = time ;
243
+ int exponent = field -> unit_exponent ;
244
+ pr_debug ("time field exponent: %d\n" , exponent );
245
+
246
+ for (;exponent < FF_TIME_EXPONENT ; exponent ++ )
247
+ scaled_time *= 10 ;
248
+ for (;exponent > FF_TIME_EXPONENT ; exponent -- )
249
+ scaled_time /= 10 ;
250
+
251
+ pr_debug ("time calculated from %d to %d\n" , time , scaled_time );
252
+ return scaled_time ;
253
+ }
254
+
234
255
static void pidff_set (struct pidff_usage * usage , u16 value )
235
256
{
236
257
usage -> value [0 ] = pidff_rescale (value , 0xffff , usage -> field );
@@ -252,6 +273,27 @@ static void pidff_set_signed(struct pidff_usage *usage, s16 value)
252
273
pr_debug ("calculated from %d to %d\n" , value , usage -> value [0 ]);
253
274
}
254
275
276
+ static void pidff_set_time (struct pidff_usage * usage , u16 time )
277
+ {
278
+ u32 modified_time = pidff_rescale_time (time , usage -> field );
279
+ usage -> value [0 ] = pidff_clamp (modified_time , usage -> field );
280
+ }
281
+
282
+ static void pidff_set_duration (struct pidff_usage * usage , u16 duration )
283
+ {
284
+ /* Convert infinite length from Linux API (0)
285
+ to PID standard (NULL) if needed */
286
+ if (duration == 0 )
287
+ duration = PID_INFINITE ;
288
+
289
+ if (duration == PID_INFINITE ) {
290
+ usage -> value [0 ] = PID_INFINITE ;
291
+ return ;
292
+ }
293
+
294
+ pidff_set_time (usage , duration );
295
+ }
296
+
255
297
/*
256
298
* Send envelope report to the device
257
299
*/
@@ -270,8 +312,10 @@ static void pidff_set_envelope_report(struct pidff_device *pidff,
270
312
0x7fff ? 0x7fff : envelope -> fade_level , 0x7fff ,
271
313
pidff -> set_envelope [PID_FADE_LEVEL ].field );
272
314
273
- pidff -> set_envelope [PID_ATTACK_TIME ].value [0 ] = envelope -> attack_length ;
274
- pidff -> set_envelope [PID_FADE_TIME ].value [0 ] = envelope -> fade_length ;
315
+ pidff_set_time (& pidff -> set_envelope [PID_ATTACK_TIME ],
316
+ envelope -> attack_length );
317
+ pidff_set_time (& pidff -> set_envelope [PID_FADE_TIME ],
318
+ envelope -> fade_length );
275
319
276
320
hid_dbg (pidff -> hid , "attack %u => %d\n" ,
277
321
envelope -> attack_level ,
@@ -340,14 +384,12 @@ static void pidff_set_effect_report(struct pidff_device *pidff,
340
384
pidff -> set_effect_type -> value [0 ] =
341
385
pidff -> create_new_effect_type -> value [0 ];
342
386
343
- /* Convert infinite length from Linux API (0)
344
- to PID standard (NULL) if needed */
345
- pidff -> set_effect [PID_DURATION ].value [0 ] =
346
- effect -> replay .length == 0 ? PID_INFINITE : effect -> replay .length ;
387
+ pidff_set_duration (& pidff -> set_effect [PID_DURATION ],
388
+ effect -> replay .length );
347
389
348
390
pidff -> set_effect [PID_TRIGGER_BUTTON ].value [0 ] = effect -> trigger .button ;
349
- pidff -> set_effect [PID_TRIGGER_REPEAT_INT ]. value [ 0 ] =
350
- effect -> trigger .interval ;
391
+ pidff_set_time ( & pidff -> set_effect [PID_TRIGGER_REPEAT_INT ],
392
+ effect -> trigger .interval ) ;
351
393
pidff -> set_effect [PID_GAIN ].value [0 ] =
352
394
pidff -> set_effect [PID_GAIN ].field -> logical_maximum ;
353
395
pidff -> set_effect [PID_DIRECTION_ENABLE ].value [0 ] = 1 ;
@@ -360,7 +402,8 @@ static void pidff_set_effect_report(struct pidff_device *pidff,
360
402
361
403
/* Omit setting delay field if it's missing */
362
404
if (!(pidff -> quirks & HID_PIDFF_QUIRK_MISSING_DELAY ))
363
- pidff -> set_effect [PID_START_DELAY ].value [0 ] = effect -> replay .delay ;
405
+ pidff_set_time (& pidff -> set_effect [PID_START_DELAY ],
406
+ effect -> replay .delay );
364
407
365
408
hid_hw_request (pidff -> hid , pidff -> reports [PID_SET_EFFECT ],
366
409
HID_REQ_SET_REPORT );
@@ -392,15 +435,11 @@ static void pidff_set_periodic_report(struct pidff_device *pidff,
392
435
pidff_set_signed (& pidff -> set_periodic [PID_OFFSET ],
393
436
effect -> u .periodic .offset );
394
437
pidff_set (& pidff -> set_periodic [PID_PHASE ], effect -> u .periodic .phase );
395
-
396
- /* Clamp period to ensure the device can play the effect */
397
- pidff -> set_periodic [PID_PERIOD ].value [0 ] =
398
- pidff_clamp (effect -> u .periodic .period ,
399
- pidff -> set_periodic [PID_PERIOD ].field );
438
+ pidff_set_time (& pidff -> set_periodic [PID_PERIOD ],
439
+ effect -> u .periodic .period );
400
440
401
441
hid_hw_request (pidff -> hid , pidff -> reports [PID_SET_PERIODIC ],
402
442
HID_REQ_SET_REPORT );
403
-
404
443
}
405
444
406
445
/*
0 commit comments