1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
4 * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com>
6 * USB/RS232 I-Force joysticks and wheels.
12 * Set the magnitude of a constant force effect
15 * Note: caller must ensure exclusive access to device
18 static int make_magnitude_modifier(struct iforce
* iforce
,
19 struct resource
* mod_chunk
, int no_alloc
, __s16 level
)
21 unsigned char data
[3];
24 mutex_lock(&iforce
->mem_mutex
);
25 if (allocate_resource(&(iforce
->device_memory
), mod_chunk
, 2,
26 iforce
->device_memory
.start
, iforce
->device_memory
.end
, 2L,
28 mutex_unlock(&iforce
->mem_mutex
);
31 mutex_unlock(&iforce
->mem_mutex
);
34 data
[0] = LO(mod_chunk
->start
);
35 data
[1] = HI(mod_chunk
->start
);
36 data
[2] = HIFIX80(level
);
38 iforce_send_packet(iforce
, FF_CMD_MAGNITUDE
, data
);
40 iforce_dump_packet(iforce
, "magnitude", FF_CMD_MAGNITUDE
, data
);
45 * Upload the component of an effect dealing with the period, phase and magnitude
48 static int make_period_modifier(struct iforce
* iforce
,
49 struct resource
* mod_chunk
, int no_alloc
,
50 __s16 magnitude
, __s16 offset
, u16 period
, u16 phase
)
52 unsigned char data
[7];
54 period
= TIME_SCALE(period
);
57 mutex_lock(&iforce
->mem_mutex
);
58 if (allocate_resource(&(iforce
->device_memory
), mod_chunk
, 0x0c,
59 iforce
->device_memory
.start
, iforce
->device_memory
.end
, 2L,
61 mutex_unlock(&iforce
->mem_mutex
);
64 mutex_unlock(&iforce
->mem_mutex
);
67 data
[0] = LO(mod_chunk
->start
);
68 data
[1] = HI(mod_chunk
->start
);
70 data
[2] = HIFIX80(magnitude
);
71 data
[3] = HIFIX80(offset
);
77 iforce_send_packet(iforce
, FF_CMD_PERIOD
, data
);
83 * Uploads the part of an effect setting the envelope of the force
86 static int make_envelope_modifier(struct iforce
* iforce
,
87 struct resource
* mod_chunk
, int no_alloc
,
88 u16 attack_duration
, __s16 initial_level
,
89 u16 fade_duration
, __s16 final_level
)
91 unsigned char data
[8];
93 attack_duration
= TIME_SCALE(attack_duration
);
94 fade_duration
= TIME_SCALE(fade_duration
);
97 mutex_lock(&iforce
->mem_mutex
);
98 if (allocate_resource(&(iforce
->device_memory
), mod_chunk
, 0x0e,
99 iforce
->device_memory
.start
, iforce
->device_memory
.end
, 2L,
101 mutex_unlock(&iforce
->mem_mutex
);
104 mutex_unlock(&iforce
->mem_mutex
);
107 data
[0] = LO(mod_chunk
->start
);
108 data
[1] = HI(mod_chunk
->start
);
110 data
[2] = LO(attack_duration
);
111 data
[3] = HI(attack_duration
);
112 data
[4] = HI(initial_level
);
114 data
[5] = LO(fade_duration
);
115 data
[6] = HI(fade_duration
);
116 data
[7] = HI(final_level
);
118 iforce_send_packet(iforce
, FF_CMD_ENVELOPE
, data
);
124 * Component of spring, friction, inertia... effects
127 static int make_condition_modifier(struct iforce
* iforce
,
128 struct resource
* mod_chunk
, int no_alloc
,
129 __u16 rsat
, __u16 lsat
, __s16 rk
, __s16 lk
, u16 db
, __s16 center
)
131 unsigned char data
[10];
134 mutex_lock(&iforce
->mem_mutex
);
135 if (allocate_resource(&(iforce
->device_memory
), mod_chunk
, 8,
136 iforce
->device_memory
.start
, iforce
->device_memory
.end
, 2L,
138 mutex_unlock(&iforce
->mem_mutex
);
141 mutex_unlock(&iforce
->mem_mutex
);
144 data
[0] = LO(mod_chunk
->start
);
145 data
[1] = HI(mod_chunk
->start
);
147 data
[2] = (100 * rk
) >> 15; /* Dangerous: the sign is extended by gcc on plateforms providing an arith shift */
148 data
[3] = (100 * lk
) >> 15; /* This code is incorrect on cpus lacking arith shift */
150 center
= (500 * center
) >> 15;
151 data
[4] = LO(center
);
152 data
[5] = HI(center
);
154 db
= (1000 * db
) >> 16;
158 data
[8] = (100 * rsat
) >> 16;
159 data
[9] = (100 * lsat
) >> 16;
161 iforce_send_packet(iforce
, FF_CMD_CONDITION
, data
);
162 iforce_dump_packet(iforce
, "condition", FF_CMD_CONDITION
, data
);
167 static unsigned char find_button(struct iforce
*iforce
, signed short button
)
171 for (i
= 1; iforce
->type
->btn
[i
] >= 0; i
++)
172 if (iforce
->type
->btn
[i
] == button
)
178 * Analyse the changes in an effect, and tell if we need to send an condition
181 static int need_condition_modifier(struct iforce
*iforce
,
182 struct ff_effect
*old
,
183 struct ff_effect
*new)
188 if (new->type
!= FF_SPRING
&& new->type
!= FF_FRICTION
) {
189 dev_warn(&iforce
->dev
->dev
, "bad effect type in %s\n",
194 for (i
= 0; i
< 2; i
++) {
195 ret
|= old
->u
.condition
[i
].right_saturation
!= new->u
.condition
[i
].right_saturation
196 || old
->u
.condition
[i
].left_saturation
!= new->u
.condition
[i
].left_saturation
197 || old
->u
.condition
[i
].right_coeff
!= new->u
.condition
[i
].right_coeff
198 || old
->u
.condition
[i
].left_coeff
!= new->u
.condition
[i
].left_coeff
199 || old
->u
.condition
[i
].deadband
!= new->u
.condition
[i
].deadband
200 || old
->u
.condition
[i
].center
!= new->u
.condition
[i
].center
;
206 * Analyse the changes in an effect, and tell if we need to send a magnitude
209 static int need_magnitude_modifier(struct iforce
*iforce
,
210 struct ff_effect
*old
,
211 struct ff_effect
*effect
)
213 if (effect
->type
!= FF_CONSTANT
) {
214 dev_warn(&iforce
->dev
->dev
, "bad effect type in %s\n",
219 return old
->u
.constant
.level
!= effect
->u
.constant
.level
;
223 * Analyse the changes in an effect, and tell if we need to send an envelope
226 static int need_envelope_modifier(struct iforce
*iforce
, struct ff_effect
*old
,
227 struct ff_effect
*effect
)
229 switch (effect
->type
) {
231 if (old
->u
.constant
.envelope
.attack_length
!= effect
->u
.constant
.envelope
.attack_length
232 || old
->u
.constant
.envelope
.attack_level
!= effect
->u
.constant
.envelope
.attack_level
233 || old
->u
.constant
.envelope
.fade_length
!= effect
->u
.constant
.envelope
.fade_length
234 || old
->u
.constant
.envelope
.fade_level
!= effect
->u
.constant
.envelope
.fade_level
)
239 if (old
->u
.periodic
.envelope
.attack_length
!= effect
->u
.periodic
.envelope
.attack_length
240 || old
->u
.periodic
.envelope
.attack_level
!= effect
->u
.periodic
.envelope
.attack_level
241 || old
->u
.periodic
.envelope
.fade_length
!= effect
->u
.periodic
.envelope
.fade_length
242 || old
->u
.periodic
.envelope
.fade_level
!= effect
->u
.periodic
.envelope
.fade_level
)
247 dev_warn(&iforce
->dev
->dev
, "bad effect type in %s\n",
255 * Analyse the changes in an effect, and tell if we need to send a periodic
258 static int need_period_modifier(struct iforce
*iforce
, struct ff_effect
*old
,
259 struct ff_effect
*new)
261 if (new->type
!= FF_PERIODIC
) {
262 dev_warn(&iforce
->dev
->dev
, "bad effect type in %s\n",
266 return (old
->u
.periodic
.period
!= new->u
.periodic
.period
267 || old
->u
.periodic
.magnitude
!= new->u
.periodic
.magnitude
268 || old
->u
.periodic
.offset
!= new->u
.periodic
.offset
269 || old
->u
.periodic
.phase
!= new->u
.periodic
.phase
);
273 * Analyse the changes in an effect, and tell if we need to send an effect
276 static int need_core(struct ff_effect
*old
, struct ff_effect
*new)
278 if (old
->direction
!= new->direction
279 || old
->trigger
.button
!= new->trigger
.button
280 || old
->trigger
.interval
!= new->trigger
.interval
281 || old
->replay
.length
!= new->replay
.length
282 || old
->replay
.delay
!= new->replay
.delay
)
288 * Send the part common to all effects to the device
290 static int make_core(struct iforce
* iforce
, u16 id
, u16 mod_id1
, u16 mod_id2
,
291 u8 effect_type
, u8 axes
, u16 duration
, u16 delay
, u16 button
,
292 u16 interval
, u16 direction
)
294 unsigned char data
[14];
296 duration
= TIME_SCALE(duration
);
297 delay
= TIME_SCALE(delay
);
298 interval
= TIME_SCALE(interval
);
301 data
[1] = effect_type
;
302 data
[2] = LO(axes
) | find_button(iforce
, button
);
304 data
[3] = LO(duration
);
305 data
[4] = HI(duration
);
307 data
[5] = HI(direction
);
309 data
[6] = LO(interval
);
310 data
[7] = HI(interval
);
312 data
[8] = LO(mod_id1
);
313 data
[9] = HI(mod_id1
);
314 data
[10] = LO(mod_id2
);
315 data
[11] = HI(mod_id2
);
317 data
[12] = LO(delay
);
318 data
[13] = HI(delay
);
321 /* iforce_control_playback(iforce, id, 0);*/
323 iforce_send_packet(iforce
, FF_CMD_EFFECT
, data
);
325 /* If needed, restart effect */
326 if (test_bit(FF_CORE_SHOULD_PLAY
, iforce
->core_effects
[id
].flags
)) {
327 /* BUG: perhaps we should replay n times, instead of 1. But we do not know n */
328 iforce_control_playback(iforce
, id
, 1);
335 * Upload a periodic effect to the device
336 * See also iforce_upload_constant.
338 int iforce_upload_periodic(struct iforce
*iforce
, struct ff_effect
*effect
, struct ff_effect
*old
)
341 int core_id
= effect
->id
;
342 struct iforce_core_effect
* core_effect
= iforce
->core_effects
+ core_id
;
343 struct resource
* mod1_chunk
= &(iforce
->core_effects
[core_id
].mod1_chunk
);
344 struct resource
* mod2_chunk
= &(iforce
->core_effects
[core_id
].mod2_chunk
);
349 if (!old
|| need_period_modifier(iforce
, old
, effect
)) {
350 param1_err
= make_period_modifier(iforce
, mod1_chunk
,
352 effect
->u
.periodic
.magnitude
, effect
->u
.periodic
.offset
,
353 effect
->u
.periodic
.period
, effect
->u
.periodic
.phase
);
356 set_bit(FF_MOD1_IS_USED
, core_effect
->flags
);
359 if (!old
|| need_envelope_modifier(iforce
, old
, effect
)) {
360 param2_err
= make_envelope_modifier(iforce
, mod2_chunk
,
362 effect
->u
.periodic
.envelope
.attack_length
,
363 effect
->u
.periodic
.envelope
.attack_level
,
364 effect
->u
.periodic
.envelope
.fade_length
,
365 effect
->u
.periodic
.envelope
.fade_level
);
368 set_bit(FF_MOD2_IS_USED
, core_effect
->flags
);
371 switch (effect
->u
.periodic
.waveform
) {
372 case FF_SQUARE
: wave_code
= 0x20; break;
373 case FF_TRIANGLE
: wave_code
= 0x21; break;
374 case FF_SINE
: wave_code
= 0x22; break;
375 case FF_SAW_UP
: wave_code
= 0x23; break;
376 case FF_SAW_DOWN
: wave_code
= 0x24; break;
377 default: wave_code
= 0x20; break;
380 if (!old
|| need_core(old
, effect
)) {
381 core_err
= make_core(iforce
, effect
->id
,
386 effect
->replay
.length
,
387 effect
->replay
.delay
,
388 effect
->trigger
.button
,
389 effect
->trigger
.interval
,
393 /* If one of the parameter creation failed, we already returned an
395 * If the core creation failed, we return its error code.
396 * Else: if one parameter at least was created, we return 0
399 return core_err
< 0 ? core_err
: (param1_err
&& param2_err
);
403 * Upload a constant force effect
406 * 0 Ok, effect created or updated
407 * 1 effect did not change since last upload, and no packet was therefore sent
409 int iforce_upload_constant(struct iforce
*iforce
, struct ff_effect
*effect
, struct ff_effect
*old
)
411 int core_id
= effect
->id
;
412 struct iforce_core_effect
* core_effect
= iforce
->core_effects
+ core_id
;
413 struct resource
* mod1_chunk
= &(iforce
->core_effects
[core_id
].mod1_chunk
);
414 struct resource
* mod2_chunk
= &(iforce
->core_effects
[core_id
].mod2_chunk
);
419 if (!old
|| need_magnitude_modifier(iforce
, old
, effect
)) {
420 param1_err
= make_magnitude_modifier(iforce
, mod1_chunk
,
422 effect
->u
.constant
.level
);
425 set_bit(FF_MOD1_IS_USED
, core_effect
->flags
);
428 if (!old
|| need_envelope_modifier(iforce
, old
, effect
)) {
429 param2_err
= make_envelope_modifier(iforce
, mod2_chunk
,
431 effect
->u
.constant
.envelope
.attack_length
,
432 effect
->u
.constant
.envelope
.attack_level
,
433 effect
->u
.constant
.envelope
.fade_length
,
434 effect
->u
.constant
.envelope
.fade_level
);
437 set_bit(FF_MOD2_IS_USED
, core_effect
->flags
);
440 if (!old
|| need_core(old
, effect
)) {
441 core_err
= make_core(iforce
, effect
->id
,
446 effect
->replay
.length
,
447 effect
->replay
.delay
,
448 effect
->trigger
.button
,
449 effect
->trigger
.interval
,
453 /* If one of the parameter creation failed, we already returned an
455 * If the core creation failed, we return its error code.
456 * Else: if one parameter at least was created, we return 0
459 return core_err
< 0 ? core_err
: (param1_err
&& param2_err
);
463 * Upload an condition effect. Those are for example friction, inertia, springs...
465 int iforce_upload_condition(struct iforce
*iforce
, struct ff_effect
*effect
, struct ff_effect
*old
)
467 int core_id
= effect
->id
;
468 struct iforce_core_effect
* core_effect
= iforce
->core_effects
+ core_id
;
469 struct resource
* mod1_chunk
= &(core_effect
->mod1_chunk
);
470 struct resource
* mod2_chunk
= &(core_effect
->mod2_chunk
);
475 switch (effect
->type
) {
476 case FF_SPRING
: type
= 0x40; break;
477 case FF_DAMPER
: type
= 0x41; break;
481 if (!old
|| need_condition_modifier(iforce
, old
, effect
)) {
482 param_err
= make_condition_modifier(iforce
, mod1_chunk
,
484 effect
->u
.condition
[0].right_saturation
,
485 effect
->u
.condition
[0].left_saturation
,
486 effect
->u
.condition
[0].right_coeff
,
487 effect
->u
.condition
[0].left_coeff
,
488 effect
->u
.condition
[0].deadband
,
489 effect
->u
.condition
[0].center
);
492 set_bit(FF_MOD1_IS_USED
, core_effect
->flags
);
494 param_err
= make_condition_modifier(iforce
, mod2_chunk
,
496 effect
->u
.condition
[1].right_saturation
,
497 effect
->u
.condition
[1].left_saturation
,
498 effect
->u
.condition
[1].right_coeff
,
499 effect
->u
.condition
[1].left_coeff
,
500 effect
->u
.condition
[1].deadband
,
501 effect
->u
.condition
[1].center
);
504 set_bit(FF_MOD2_IS_USED
, core_effect
->flags
);
508 if (!old
|| need_core(old
, effect
)) {
509 core_err
= make_core(iforce
, effect
->id
,
510 mod1_chunk
->start
, mod2_chunk
->start
,
512 effect
->replay
.length
, effect
->replay
.delay
,
513 effect
->trigger
.button
, effect
->trigger
.interval
,
517 /* If the parameter creation failed, we already returned an
519 * If the core creation failed, we return its error code.
520 * Else: if a parameter was created, we return 0
523 return core_err
< 0 ? core_err
: param_err
;