xref: /openbmc/linux/drivers/input/joystick/iforce/iforce-ff.c (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1 /*
2  * $Id: iforce-ff.c,v 1.9 2002/02/02 19:28:35 jdeneux Exp $
3  *
4  *  Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz>
5  *  Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com>
6  *
7  *  USB/RS232 I-Force joysticks and wheels.
8  */
9 
10 /*
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24  *
25  * Should you need to contact me, the author, you can do so either by
26  * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
27  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
28  */
29 
30 #include "iforce.h"
31 
32 /*
33  * Set the magnitude of a constant force effect
34  * Return error code
35  *
36  * Note: caller must ensure exclusive access to device
37  */
38 
39 static int make_magnitude_modifier(struct iforce* iforce,
40 	struct resource* mod_chunk, int no_alloc, __s16 level)
41 {
42 	unsigned char data[3];
43 
44 	if (!no_alloc) {
45 		down(&iforce->mem_mutex);
46 		if (allocate_resource(&(iforce->device_memory), mod_chunk, 2,
47 			iforce->device_memory.start, iforce->device_memory.end, 2L,
48 			NULL, NULL)) {
49 			up(&iforce->mem_mutex);
50 			return -ENOMEM;
51 		}
52 		up(&iforce->mem_mutex);
53 	}
54 
55 	data[0] = LO(mod_chunk->start);
56 	data[1] = HI(mod_chunk->start);
57 	data[2] = HIFIX80(level);
58 
59 	iforce_send_packet(iforce, FF_CMD_MAGNITUDE, data);
60 
61 	iforce_dump_packet("magnitude: ", FF_CMD_MAGNITUDE, data);
62 	return 0;
63 }
64 
65 /*
66  * Upload the component of an effect dealing with the period, phase and magnitude
67  */
68 
69 static int make_period_modifier(struct iforce* iforce,
70 	struct resource* mod_chunk, int no_alloc,
71 	__s16 magnitude, __s16 offset, u16 period, u16 phase)
72 {
73 	unsigned char data[7];
74 
75 	period = TIME_SCALE(period);
76 
77 	if (!no_alloc) {
78 		down(&iforce->mem_mutex);
79 		if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0c,
80 			iforce->device_memory.start, iforce->device_memory.end, 2L,
81 			NULL, NULL)) {
82 			up(&iforce->mem_mutex);
83 			return -ENOMEM;
84 		}
85 		up(&iforce->mem_mutex);
86 	}
87 
88 	data[0] = LO(mod_chunk->start);
89 	data[1] = HI(mod_chunk->start);
90 
91 	data[2] = HIFIX80(magnitude);
92 	data[3] = HIFIX80(offset);
93 	data[4] = HI(phase);
94 
95 	data[5] = LO(period);
96 	data[6] = HI(period);
97 
98 	iforce_send_packet(iforce, FF_CMD_PERIOD, data);
99 
100 	return 0;
101 }
102 
103 /*
104  * Uploads the part of an effect setting the envelope of the force
105  */
106 
107 static int make_envelope_modifier(struct iforce* iforce,
108 	struct resource* mod_chunk, int no_alloc,
109 	u16 attack_duration, __s16 initial_level,
110 	u16 fade_duration, __s16 final_level)
111 {
112 	unsigned char data[8];
113 
114 	attack_duration = TIME_SCALE(attack_duration);
115 	fade_duration = TIME_SCALE(fade_duration);
116 
117 	if (!no_alloc) {
118 		down(&iforce->mem_mutex);
119 		if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0e,
120 			iforce->device_memory.start, iforce->device_memory.end, 2L,
121 			NULL, NULL)) {
122 			up(&iforce->mem_mutex);
123 			return -ENOMEM;
124 		}
125 		up(&iforce->mem_mutex);
126 	}
127 
128 	data[0] = LO(mod_chunk->start);
129 	data[1] = HI(mod_chunk->start);
130 
131 	data[2] = LO(attack_duration);
132 	data[3] = HI(attack_duration);
133 	data[4] = HI(initial_level);
134 
135 	data[5] = LO(fade_duration);
136 	data[6] = HI(fade_duration);
137 	data[7] = HI(final_level);
138 
139 	iforce_send_packet(iforce, FF_CMD_ENVELOPE, data);
140 
141 	return 0;
142 }
143 
144 /*
145  * Component of spring, friction, inertia... effects
146  */
147 
148 static int make_condition_modifier(struct iforce* iforce,
149 	struct resource* mod_chunk, int no_alloc,
150 	__u16 rsat, __u16 lsat, __s16 rk, __s16 lk, u16 db, __s16 center)
151 {
152 	unsigned char data[10];
153 
154 	if (!no_alloc) {
155 		down(&iforce->mem_mutex);
156 		if (allocate_resource(&(iforce->device_memory), mod_chunk, 8,
157 			iforce->device_memory.start, iforce->device_memory.end, 2L,
158 			NULL, NULL)) {
159 			up(&iforce->mem_mutex);
160 			return -ENOMEM;
161 		}
162 		up(&iforce->mem_mutex);
163 	}
164 
165 	data[0] = LO(mod_chunk->start);
166 	data[1] = HI(mod_chunk->start);
167 
168 	data[2] = (100*rk)>>15;	/* Dangerous: the sign is extended by gcc on plateforms providing an arith shift */
169 	data[3] = (100*lk)>>15; /* This code is incorrect on cpus lacking arith shift */
170 
171 	center = (500*center)>>15;
172 	data[4] = LO(center);
173 	data[5] = HI(center);
174 
175 	db = (1000*db)>>16;
176 	data[6] = LO(db);
177 	data[7] = HI(db);
178 
179 	data[8] = (100*rsat)>>16;
180 	data[9] = (100*lsat)>>16;
181 
182 	iforce_send_packet(iforce, FF_CMD_CONDITION, data);
183 	iforce_dump_packet("condition", FF_CMD_CONDITION, data);
184 
185 	return 0;
186 }
187 
188 static unsigned char find_button(struct iforce *iforce, signed short button)
189 {
190 	int i;
191 	for (i = 1; iforce->type->btn[i] >= 0; i++)
192 		if (iforce->type->btn[i] == button)
193 			return i + 1;
194 	return 0;
195 }
196 
197 /*
198  * Analyse the changes in an effect, and tell if we need to send an condition
199  * parameter packet
200  */
201 static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new)
202 {
203 	int id = new->id;
204 	struct ff_effect* old = &iforce->core_effects[id].effect;
205 	int ret=0;
206 	int i;
207 
208 	if (new->type != FF_SPRING && new->type != FF_FRICTION) {
209 		printk(KERN_WARNING "iforce.c: bad effect type in need_condition_modifier\n");
210 		return FALSE;
211 	}
212 
213 	for(i=0; i<2; i++) {
214 		ret |= old->u.condition[i].right_saturation != new->u.condition[i].right_saturation
215 			|| old->u.condition[i].left_saturation != new->u.condition[i].left_saturation
216 			|| old->u.condition[i].right_coeff != new->u.condition[i].right_coeff
217 			|| old->u.condition[i].left_coeff != new->u.condition[i].left_coeff
218 			|| old->u.condition[i].deadband != new->u.condition[i].deadband
219 			|| old->u.condition[i].center != new->u.condition[i].center;
220 	}
221 	return ret;
222 }
223 
224 /*
225  * Analyse the changes in an effect, and tell if we need to send a magnitude
226  * parameter packet
227  */
228 static int need_magnitude_modifier(struct iforce* iforce, struct ff_effect* effect)
229 {
230 	int id = effect->id;
231 	struct ff_effect* old = &iforce->core_effects[id].effect;
232 
233 	if (effect->type != FF_CONSTANT) {
234 		printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n");
235 		return FALSE;
236 	}
237 
238 	return (old->u.constant.level != effect->u.constant.level);
239 }
240 
241 /*
242  * Analyse the changes in an effect, and tell if we need to send an envelope
243  * parameter packet
244  */
245 static int need_envelope_modifier(struct iforce* iforce, struct ff_effect* effect)
246 {
247 	int id = effect->id;
248 	struct ff_effect* old = &iforce->core_effects[id].effect;
249 
250 	switch (effect->type) {
251 	case FF_CONSTANT:
252 		if (old->u.constant.envelope.attack_length != effect->u.constant.envelope.attack_length
253 		|| old->u.constant.envelope.attack_level != effect->u.constant.envelope.attack_level
254 		|| old->u.constant.envelope.fade_length != effect->u.constant.envelope.fade_length
255 		|| old->u.constant.envelope.fade_level != effect->u.constant.envelope.fade_level)
256 			return TRUE;
257 		break;
258 
259 	case FF_PERIODIC:
260 		if (old->u.periodic.envelope.attack_length != effect->u.periodic.envelope.attack_length
261 		|| old->u.periodic.envelope.attack_level != effect->u.periodic.envelope.attack_level
262 		|| old->u.periodic.envelope.fade_length != effect->u.periodic.envelope.fade_length
263 		|| old->u.periodic.envelope.fade_level != effect->u.periodic.envelope.fade_level)
264 			return TRUE;
265 		break;
266 
267 	default:
268 		printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n");
269 	}
270 
271 	return FALSE;
272 }
273 
274 /*
275  * Analyse the changes in an effect, and tell if we need to send a periodic
276  * parameter effect
277  */
278 static int need_period_modifier(struct iforce* iforce, struct ff_effect* new)
279 {
280 	int id = new->id;
281 	struct ff_effect* old = &iforce->core_effects[id].effect;
282 
283 	if (new->type != FF_PERIODIC) {
284 		printk(KERN_WARNING "iforce.c: bad effect type in need_periodic_modifier\n");
285 		return FALSE;
286 	}
287 
288 	return (old->u.periodic.period != new->u.periodic.period
289 		|| old->u.periodic.magnitude != new->u.periodic.magnitude
290 		|| old->u.periodic.offset != new->u.periodic.offset
291 		|| old->u.periodic.phase != new->u.periodic.phase);
292 }
293 
294 /*
295  * Analyse the changes in an effect, and tell if we need to send an effect
296  * packet
297  */
298 static int need_core(struct iforce* iforce, struct ff_effect* new)
299 {
300 	int id = new->id;
301 	struct ff_effect* old = &iforce->core_effects[id].effect;
302 
303 	if (old->direction != new->direction
304 		|| old->trigger.button != new->trigger.button
305 		|| old->trigger.interval != new->trigger.interval
306 		|| old->replay.length != new->replay.length
307 		|| old->replay.delay != new->replay.delay)
308 		return TRUE;
309 
310 	return FALSE;
311 }
312 /*
313  * Send the part common to all effects to the device
314  */
315 static int make_core(struct iforce* iforce, u16 id, u16 mod_id1, u16 mod_id2,
316 	u8 effect_type, u8 axes, u16 duration, u16 delay, u16 button,
317 	u16 interval, u16 direction)
318 {
319 	unsigned char data[14];
320 
321 	duration = TIME_SCALE(duration);
322 	delay    = TIME_SCALE(delay);
323 	interval = TIME_SCALE(interval);
324 
325 	data[0]  = LO(id);
326 	data[1]  = effect_type;
327 	data[2]  = LO(axes) | find_button(iforce, button);
328 
329 	data[3]  = LO(duration);
330 	data[4]  = HI(duration);
331 
332 	data[5]  = HI(direction);
333 
334 	data[6]  = LO(interval);
335 	data[7]  = HI(interval);
336 
337 	data[8]  = LO(mod_id1);
338 	data[9]  = HI(mod_id1);
339 	data[10] = LO(mod_id2);
340 	data[11] = HI(mod_id2);
341 
342 	data[12] = LO(delay);
343 	data[13] = HI(delay);
344 
345 	/* Stop effect */
346 /*	iforce_control_playback(iforce, id, 0);*/
347 
348 	iforce_send_packet(iforce, FF_CMD_EFFECT, data);
349 
350 	/* If needed, restart effect */
351 	if (test_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[id].flags)) {
352 		/* BUG: perhaps we should replay n times, instead of 1. But we do not know n */
353 		iforce_control_playback(iforce, id, 1);
354 	}
355 
356 	return 0;
357 }
358 
359 /*
360  * Upload a periodic effect to the device
361  * See also iforce_upload_constant.
362  */
363 int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int is_update)
364 {
365 	u8 wave_code;
366 	int core_id = effect->id;
367 	struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
368 	struct resource* mod1_chunk = &(iforce->core_effects[core_id].mod1_chunk);
369 	struct resource* mod2_chunk = &(iforce->core_effects[core_id].mod2_chunk);
370 	int param1_err = 1;
371 	int param2_err = 1;
372 	int core_err = 0;
373 
374 	if (!is_update || need_period_modifier(iforce, effect)) {
375 		param1_err = make_period_modifier(iforce, mod1_chunk,
376 			is_update,
377 			effect->u.periodic.magnitude, effect->u.periodic.offset,
378 			effect->u.periodic.period, effect->u.periodic.phase);
379 		if (param1_err) return param1_err;
380 		set_bit(FF_MOD1_IS_USED, core_effect->flags);
381 	}
382 
383 	if (!is_update || need_envelope_modifier(iforce, effect)) {
384 		param2_err = make_envelope_modifier(iforce, mod2_chunk,
385 			is_update,
386 			effect->u.periodic.envelope.attack_length,
387 			effect->u.periodic.envelope.attack_level,
388 			effect->u.periodic.envelope.fade_length,
389 			effect->u.periodic.envelope.fade_level);
390 		if (param2_err) return param2_err;
391 		set_bit(FF_MOD2_IS_USED, core_effect->flags);
392 	}
393 
394 	switch (effect->u.periodic.waveform) {
395 		case FF_SQUARE:		wave_code = 0x20; break;
396 		case FF_TRIANGLE:	wave_code = 0x21; break;
397 		case FF_SINE:		wave_code = 0x22; break;
398 		case FF_SAW_UP:		wave_code = 0x23; break;
399 		case FF_SAW_DOWN:	wave_code = 0x24; break;
400 		default:		wave_code = 0x20; break;
401 	}
402 
403 	if (!is_update || need_core(iforce, effect)) {
404 		core_err = make_core(iforce, effect->id,
405 			mod1_chunk->start,
406 			mod2_chunk->start,
407 			wave_code,
408 			0x20,
409 			effect->replay.length,
410 			effect->replay.delay,
411 			effect->trigger.button,
412 			effect->trigger.interval,
413 			effect->direction);
414 	}
415 
416 	/* If one of the parameter creation failed, we already returned an
417 	 * error code.
418 	 * If the core creation failed, we return its error code.
419 	 * Else: if one parameter at least was created, we return 0
420 	 *       else we return 1;
421 	 */
422 	return core_err < 0 ? core_err : (param1_err && param2_err);
423 }
424 
425 /*
426  * Upload a constant force effect
427  * Return value:
428  *  <0 Error code
429  *  0 Ok, effect created or updated
430  *  1 effect did not change since last upload, and no packet was therefore sent
431  */
432 int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int is_update)
433 {
434 	int core_id = effect->id;
435 	struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
436 	struct resource* mod1_chunk = &(iforce->core_effects[core_id].mod1_chunk);
437 	struct resource* mod2_chunk = &(iforce->core_effects[core_id].mod2_chunk);
438 	int param1_err = 1;
439 	int param2_err = 1;
440 	int core_err = 0;
441 
442 	if (!is_update || need_magnitude_modifier(iforce, effect)) {
443 		param1_err = make_magnitude_modifier(iforce, mod1_chunk,
444 			is_update,
445 			effect->u.constant.level);
446 		if (param1_err) return param1_err;
447 		set_bit(FF_MOD1_IS_USED, core_effect->flags);
448 	}
449 
450 	if (!is_update || need_envelope_modifier(iforce, effect)) {
451 		param2_err = make_envelope_modifier(iforce, mod2_chunk,
452 			is_update,
453 			effect->u.constant.envelope.attack_length,
454 			effect->u.constant.envelope.attack_level,
455 			effect->u.constant.envelope.fade_length,
456 			effect->u.constant.envelope.fade_level);
457 		if (param2_err) return param2_err;
458 		set_bit(FF_MOD2_IS_USED, core_effect->flags);
459 	}
460 
461 	if (!is_update || need_core(iforce, effect)) {
462 		core_err = make_core(iforce, effect->id,
463 			mod1_chunk->start,
464 			mod2_chunk->start,
465 			0x00,
466 			0x20,
467 			effect->replay.length,
468 			effect->replay.delay,
469 			effect->trigger.button,
470 			effect->trigger.interval,
471 			effect->direction);
472 	}
473 
474 	/* If one of the parameter creation failed, we already returned an
475 	 * error code.
476 	 * If the core creation failed, we return its error code.
477 	 * Else: if one parameter at least was created, we return 0
478 	 *       else we return 1;
479 	 */
480 	return core_err < 0 ? core_err : (param1_err && param2_err);
481 }
482 
483 /*
484  * Upload an condition effect. Those are for example friction, inertia, springs...
485  */
486 int iforce_upload_condition(struct iforce* iforce, struct ff_effect* effect, int is_update)
487 {
488 	int core_id = effect->id;
489 	struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
490 	struct resource* mod1_chunk = &(core_effect->mod1_chunk);
491 	struct resource* mod2_chunk = &(core_effect->mod2_chunk);
492 	u8 type;
493 	int param_err = 1;
494 	int core_err = 0;
495 
496 	switch (effect->type) {
497 		case FF_SPRING:		type = 0x40; break;
498 		case FF_DAMPER:		type = 0x41; break;
499 		default: return -1;
500 	}
501 
502 	if (!is_update || need_condition_modifier(iforce, effect)) {
503 		param_err = make_condition_modifier(iforce, mod1_chunk,
504 			is_update,
505 			effect->u.condition[0].right_saturation,
506 			effect->u.condition[0].left_saturation,
507 			effect->u.condition[0].right_coeff,
508 			effect->u.condition[0].left_coeff,
509 			effect->u.condition[0].deadband,
510 			effect->u.condition[0].center);
511 		if (param_err) return param_err;
512 		set_bit(FF_MOD1_IS_USED, core_effect->flags);
513 
514 		param_err = make_condition_modifier(iforce, mod2_chunk,
515 			is_update,
516 			effect->u.condition[1].right_saturation,
517 			effect->u.condition[1].left_saturation,
518 			effect->u.condition[1].right_coeff,
519 			effect->u.condition[1].left_coeff,
520 			effect->u.condition[1].deadband,
521 			effect->u.condition[1].center);
522 		if (param_err) return param_err;
523 		set_bit(FF_MOD2_IS_USED, core_effect->flags);
524 
525 	}
526 
527 	if (!is_update || need_core(iforce, effect)) {
528 		core_err = make_core(iforce, effect->id,
529 			mod1_chunk->start, mod2_chunk->start,
530 			type, 0xc0,
531 			effect->replay.length, effect->replay.delay,
532 			effect->trigger.button, effect->trigger.interval,
533 			effect->direction);
534 	}
535 
536 	/* If the parameter creation failed, we already returned an
537 	 * error code.
538 	 * If the core creation failed, we return its error code.
539 	 * Else: if a parameter  was created, we return 0
540 	 *       else we return 1;
541 	 */
542 	return core_err < 0 ? core_err : param_err;
543 }
544