aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnssi Hannula <anssi.hannula@gmail.com>2006-07-19 01:40:39 -0400
committerDmitry Torokhov <dtor@insightbb.com>2006-07-19 01:40:39 -0400
commitf6a01c85965c9e6fa8fb893c1fa5db16130d0ccb (patch)
treed23d6607c6167109cffb203e8b427824c979af94
parent7d928a2b14eede1f333db7b7b684c57f7fa7f456 (diff)
Input: iforce - switch to the new FF interface
Signed-off-by: Anssi Hannula <anssi.hannula@gmail.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/joystick/iforce/iforce-ff.c118
-rw-r--r--drivers/input/joystick/iforce/iforce-main.c226
-rw-r--r--drivers/input/joystick/iforce/iforce-packets.c15
-rw-r--r--drivers/input/joystick/iforce/iforce.h26
4 files changed, 147 insertions, 238 deletions
diff --git a/drivers/input/joystick/iforce/iforce-ff.c b/drivers/input/joystick/iforce/iforce-ff.c
index 50c90765aee1..8fb0c19cc60e 100644
--- a/drivers/input/joystick/iforce/iforce-ff.c
+++ b/drivers/input/joystick/iforce/iforce-ff.c
@@ -165,19 +165,19 @@ static int make_condition_modifier(struct iforce* iforce,
165 data[0] = LO(mod_chunk->start); 165 data[0] = LO(mod_chunk->start);
166 data[1] = HI(mod_chunk->start); 166 data[1] = HI(mod_chunk->start);
167 167
168 data[2] = (100*rk)>>15; /* Dangerous: the sign is extended by gcc on plateforms providing an arith shift */ 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 */ 169 data[3] = (100 * lk) >> 15; /* This code is incorrect on cpus lacking arith shift */
170 170
171 center = (500*center)>>15; 171 center = (500 * center) >> 15;
172 data[4] = LO(center); 172 data[4] = LO(center);
173 data[5] = HI(center); 173 data[5] = HI(center);
174 174
175 db = (1000*db)>>16; 175 db = (1000 * db) >> 16;
176 data[6] = LO(db); 176 data[6] = LO(db);
177 data[7] = HI(db); 177 data[7] = HI(db);
178 178
179 data[8] = (100*rsat)>>16; 179 data[8] = (100 * rsat) >> 16;
180 data[9] = (100*lsat)>>16; 180 data[9] = (100 * lsat) >> 16;
181 181
182 iforce_send_packet(iforce, FF_CMD_CONDITION, data); 182 iforce_send_packet(iforce, FF_CMD_CONDITION, data);
183 iforce_dump_packet("condition", FF_CMD_CONDITION, data); 183 iforce_dump_packet("condition", FF_CMD_CONDITION, data);
@@ -188,6 +188,7 @@ static int make_condition_modifier(struct iforce* iforce,
188static unsigned char find_button(struct iforce *iforce, signed short button) 188static unsigned char find_button(struct iforce *iforce, signed short button)
189{ 189{
190 int i; 190 int i;
191
191 for (i = 1; iforce->type->btn[i] >= 0; i++) 192 for (i = 1; iforce->type->btn[i] >= 0; i++)
192 if (iforce->type->btn[i] == button) 193 if (iforce->type->btn[i] == button)
193 return i + 1; 194 return i + 1;
@@ -198,19 +199,17 @@ static unsigned char find_button(struct iforce *iforce, signed short button)
198 * Analyse the changes in an effect, and tell if we need to send an condition 199 * Analyse the changes in an effect, and tell if we need to send an condition
199 * parameter packet 200 * parameter packet
200 */ 201 */
201static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new) 202static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new)
202{ 203{
203 int id = new->id; 204 int ret = 0;
204 struct ff_effect* old = &iforce->core_effects[id].effect;
205 int ret=0;
206 int i; 205 int i;
207 206
208 if (new->type != FF_SPRING && new->type != FF_FRICTION) { 207 if (new->type != FF_SPRING && new->type != FF_FRICTION) {
209 printk(KERN_WARNING "iforce.c: bad effect type in need_condition_modifier\n"); 208 printk(KERN_WARNING "iforce.c: bad effect type in need_condition_modifier\n");
210 return FALSE; 209 return 0;
211 } 210 }
212 211
213 for(i=0; i<2; i++) { 212 for (i = 0; i < 2; i++) {
214 ret |= old->u.condition[i].right_saturation != new->u.condition[i].right_saturation 213 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 214 || 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 215 || old->u.condition[i].right_coeff != new->u.condition[i].right_coeff
@@ -225,35 +224,29 @@ static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new)
225 * Analyse the changes in an effect, and tell if we need to send a magnitude 224 * Analyse the changes in an effect, and tell if we need to send a magnitude
226 * parameter packet 225 * parameter packet
227 */ 226 */
228static int need_magnitude_modifier(struct iforce* iforce, struct ff_effect* effect) 227static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effect)
229{ 228{
230 int id = effect->id;
231 struct ff_effect* old = &iforce->core_effects[id].effect;
232
233 if (effect->type != FF_CONSTANT) { 229 if (effect->type != FF_CONSTANT) {
234 printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n"); 230 printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n");
235 return FALSE; 231 return 0;
236 } 232 }
237 233
238 return (old->u.constant.level != effect->u.constant.level); 234 return old->u.constant.level != effect->u.constant.level;
239} 235}
240 236
241/* 237/*
242 * Analyse the changes in an effect, and tell if we need to send an envelope 238 * Analyse the changes in an effect, and tell if we need to send an envelope
243 * parameter packet 239 * parameter packet
244 */ 240 */
245static int need_envelope_modifier(struct iforce* iforce, struct ff_effect* effect) 241static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effect)
246{ 242{
247 int id = effect->id;
248 struct ff_effect* old = &iforce->core_effects[id].effect;
249
250 switch (effect->type) { 243 switch (effect->type) {
251 case FF_CONSTANT: 244 case FF_CONSTANT:
252 if (old->u.constant.envelope.attack_length != effect->u.constant.envelope.attack_length 245 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 246 || 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 247 || 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) 248 || old->u.constant.envelope.fade_level != effect->u.constant.envelope.fade_level)
256 return TRUE; 249 return 1;
257 break; 250 break;
258 251
259 case FF_PERIODIC: 252 case FF_PERIODIC:
@@ -261,30 +254,26 @@ static int need_envelope_modifier(struct iforce* iforce, struct ff_effect* effec
261 || old->u.periodic.envelope.attack_level != effect->u.periodic.envelope.attack_level 254 || 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 255 || 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) 256 || old->u.periodic.envelope.fade_level != effect->u.periodic.envelope.fade_level)
264 return TRUE; 257 return 1;
265 break; 258 break;
266 259
267 default: 260 default:
268 printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n"); 261 printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n");
269 } 262 }
270 263
271 return FALSE; 264 return 0;
272} 265}
273 266
274/* 267/*
275 * Analyse the changes in an effect, and tell if we need to send a periodic 268 * Analyse the changes in an effect, and tell if we need to send a periodic
276 * parameter effect 269 * parameter effect
277 */ 270 */
278static int need_period_modifier(struct iforce* iforce, struct ff_effect* new) 271static int need_period_modifier(struct ff_effect *old, struct ff_effect *new)
279{ 272{
280 int id = new->id;
281 struct ff_effect* old = &iforce->core_effects[id].effect;
282
283 if (new->type != FF_PERIODIC) { 273 if (new->type != FF_PERIODIC) {
284 printk(KERN_WARNING "iforce.c: bad effect type in need_periodic_modifier\n"); 274 printk(KERN_WARNING "iforce.c: bad effect type in need_period_modifier\n");
285 return FALSE; 275 return 0;
286 } 276 }
287
288 return (old->u.periodic.period != new->u.periodic.period 277 return (old->u.periodic.period != new->u.periodic.period
289 || old->u.periodic.magnitude != new->u.periodic.magnitude 278 || old->u.periodic.magnitude != new->u.periodic.magnitude
290 || old->u.periodic.offset != new->u.periodic.offset 279 || old->u.periodic.offset != new->u.periodic.offset
@@ -295,19 +284,16 @@ static int need_period_modifier(struct iforce* iforce, struct ff_effect* new)
295 * Analyse the changes in an effect, and tell if we need to send an effect 284 * Analyse the changes in an effect, and tell if we need to send an effect
296 * packet 285 * packet
297 */ 286 */
298static int need_core(struct iforce* iforce, struct ff_effect* new) 287static int need_core(struct ff_effect *old, struct ff_effect *new)
299{ 288{
300 int id = new->id;
301 struct ff_effect* old = &iforce->core_effects[id].effect;
302
303 if (old->direction != new->direction 289 if (old->direction != new->direction
304 || old->trigger.button != new->trigger.button 290 || old->trigger.button != new->trigger.button
305 || old->trigger.interval != new->trigger.interval 291 || old->trigger.interval != new->trigger.interval
306 || old->replay.length != new->replay.length 292 || old->replay.length != new->replay.length
307 || old->replay.delay != new->replay.delay) 293 || old->replay.delay != new->replay.delay)
308 return TRUE; 294 return 1;
309 295
310 return FALSE; 296 return 0;
311} 297}
312/* 298/*
313 * Send the part common to all effects to the device 299 * Send the part common to all effects to the device
@@ -360,7 +346,7 @@ static int make_core(struct iforce* iforce, u16 id, u16 mod_id1, u16 mod_id2,
360 * Upload a periodic effect to the device 346 * Upload a periodic effect to the device
361 * See also iforce_upload_constant. 347 * See also iforce_upload_constant.
362 */ 348 */
363int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int is_update) 349int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
364{ 350{
365 u8 wave_code; 351 u8 wave_code;
366 int core_id = effect->id; 352 int core_id = effect->id;
@@ -371,23 +357,25 @@ int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int
371 int param2_err = 1; 357 int param2_err = 1;
372 int core_err = 0; 358 int core_err = 0;
373 359
374 if (!is_update || need_period_modifier(iforce, effect)) { 360 if (!old || need_period_modifier(old, effect)) {
375 param1_err = make_period_modifier(iforce, mod1_chunk, 361 param1_err = make_period_modifier(iforce, mod1_chunk,
376 is_update, 362 old != NULL,
377 effect->u.periodic.magnitude, effect->u.periodic.offset, 363 effect->u.periodic.magnitude, effect->u.periodic.offset,
378 effect->u.periodic.period, effect->u.periodic.phase); 364 effect->u.periodic.period, effect->u.periodic.phase);
379 if (param1_err) return param1_err; 365 if (param1_err)
366 return param1_err;
380 set_bit(FF_MOD1_IS_USED, core_effect->flags); 367 set_bit(FF_MOD1_IS_USED, core_effect->flags);
381 } 368 }
382 369
383 if (!is_update || need_envelope_modifier(iforce, effect)) { 370 if (!old || need_envelope_modifier(old, effect)) {
384 param2_err = make_envelope_modifier(iforce, mod2_chunk, 371 param2_err = make_envelope_modifier(iforce, mod2_chunk,
385 is_update, 372 old !=NULL,
386 effect->u.periodic.envelope.attack_length, 373 effect->u.periodic.envelope.attack_length,
387 effect->u.periodic.envelope.attack_level, 374 effect->u.periodic.envelope.attack_level,
388 effect->u.periodic.envelope.fade_length, 375 effect->u.periodic.envelope.fade_length,
389 effect->u.periodic.envelope.fade_level); 376 effect->u.periodic.envelope.fade_level);
390 if (param2_err) return param2_err; 377 if (param2_err)
378 return param2_err;
391 set_bit(FF_MOD2_IS_USED, core_effect->flags); 379 set_bit(FF_MOD2_IS_USED, core_effect->flags);
392 } 380 }
393 381
@@ -400,7 +388,7 @@ int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int
400 default: wave_code = 0x20; break; 388 default: wave_code = 0x20; break;
401 } 389 }
402 390
403 if (!is_update || need_core(iforce, effect)) { 391 if (!old || need_core(old, effect)) {
404 core_err = make_core(iforce, effect->id, 392 core_err = make_core(iforce, effect->id,
405 mod1_chunk->start, 393 mod1_chunk->start,
406 mod2_chunk->start, 394 mod2_chunk->start,
@@ -429,7 +417,7 @@ int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int
429 * 0 Ok, effect created or updated 417 * 0 Ok, effect created or updated
430 * 1 effect did not change since last upload, and no packet was therefore sent 418 * 1 effect did not change since last upload, and no packet was therefore sent
431 */ 419 */
432int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int is_update) 420int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
433{ 421{
434 int core_id = effect->id; 422 int core_id = effect->id;
435 struct iforce_core_effect* core_effect = iforce->core_effects + core_id; 423 struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
@@ -439,26 +427,28 @@ int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int
439 int param2_err = 1; 427 int param2_err = 1;
440 int core_err = 0; 428 int core_err = 0;
441 429
442 if (!is_update || need_magnitude_modifier(iforce, effect)) { 430 if (!old || need_magnitude_modifier(old, effect)) {
443 param1_err = make_magnitude_modifier(iforce, mod1_chunk, 431 param1_err = make_magnitude_modifier(iforce, mod1_chunk,
444 is_update, 432 old != NULL,
445 effect->u.constant.level); 433 effect->u.constant.level);
446 if (param1_err) return param1_err; 434 if (param1_err)
435 return param1_err;
447 set_bit(FF_MOD1_IS_USED, core_effect->flags); 436 set_bit(FF_MOD1_IS_USED, core_effect->flags);
448 } 437 }
449 438
450 if (!is_update || need_envelope_modifier(iforce, effect)) { 439 if (!old || need_envelope_modifier(old, effect)) {
451 param2_err = make_envelope_modifier(iforce, mod2_chunk, 440 param2_err = make_envelope_modifier(iforce, mod2_chunk,
452 is_update, 441 old != NULL,
453 effect->u.constant.envelope.attack_length, 442 effect->u.constant.envelope.attack_length,
454 effect->u.constant.envelope.attack_level, 443 effect->u.constant.envelope.attack_level,
455 effect->u.constant.envelope.fade_length, 444 effect->u.constant.envelope.fade_length,
456 effect->u.constant.envelope.fade_level); 445 effect->u.constant.envelope.fade_level);
457 if (param2_err) return param2_err; 446 if (param2_err)
447 return param2_err;
458 set_bit(FF_MOD2_IS_USED, core_effect->flags); 448 set_bit(FF_MOD2_IS_USED, core_effect->flags);
459 } 449 }
460 450
461 if (!is_update || need_core(iforce, effect)) { 451 if (!old || need_core(old, effect)) {
462 core_err = make_core(iforce, effect->id, 452 core_err = make_core(iforce, effect->id,
463 mod1_chunk->start, 453 mod1_chunk->start,
464 mod2_chunk->start, 454 mod2_chunk->start,
@@ -483,7 +473,7 @@ int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int
483/* 473/*
484 * Upload an condition effect. Those are for example friction, inertia, springs... 474 * Upload an condition effect. Those are for example friction, inertia, springs...
485 */ 475 */
486int iforce_upload_condition(struct iforce* iforce, struct ff_effect* effect, int is_update) 476int iforce_upload_condition(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
487{ 477{
488 int core_id = effect->id; 478 int core_id = effect->id;
489 struct iforce_core_effect* core_effect = iforce->core_effects + core_id; 479 struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
@@ -494,37 +484,39 @@ int iforce_upload_condition(struct iforce* iforce, struct ff_effect* effect, int
494 int core_err = 0; 484 int core_err = 0;
495 485
496 switch (effect->type) { 486 switch (effect->type) {
497 case FF_SPRING: type = 0x40; break; 487 case FF_SPRING: type = 0x40; break;
498 case FF_DAMPER: type = 0x41; break; 488 case FF_DAMPER: type = 0x41; break;
499 default: return -1; 489 default: return -1;
500 } 490 }
501 491
502 if (!is_update || need_condition_modifier(iforce, effect)) { 492 if (!old || need_condition_modifier(old, effect)) {
503 param_err = make_condition_modifier(iforce, mod1_chunk, 493 param_err = make_condition_modifier(iforce, mod1_chunk,
504 is_update, 494 old != NULL,
505 effect->u.condition[0].right_saturation, 495 effect->u.condition[0].right_saturation,
506 effect->u.condition[0].left_saturation, 496 effect->u.condition[0].left_saturation,
507 effect->u.condition[0].right_coeff, 497 effect->u.condition[0].right_coeff,
508 effect->u.condition[0].left_coeff, 498 effect->u.condition[0].left_coeff,
509 effect->u.condition[0].deadband, 499 effect->u.condition[0].deadband,
510 effect->u.condition[0].center); 500 effect->u.condition[0].center);
511 if (param_err) return param_err; 501 if (param_err)
502 return param_err;
512 set_bit(FF_MOD1_IS_USED, core_effect->flags); 503 set_bit(FF_MOD1_IS_USED, core_effect->flags);
513 504
514 param_err = make_condition_modifier(iforce, mod2_chunk, 505 param_err = make_condition_modifier(iforce, mod2_chunk,
515 is_update, 506 old != NULL,
516 effect->u.condition[1].right_saturation, 507 effect->u.condition[1].right_saturation,
517 effect->u.condition[1].left_saturation, 508 effect->u.condition[1].left_saturation,
518 effect->u.condition[1].right_coeff, 509 effect->u.condition[1].right_coeff,
519 effect->u.condition[1].left_coeff, 510 effect->u.condition[1].left_coeff,
520 effect->u.condition[1].deadband, 511 effect->u.condition[1].deadband,
521 effect->u.condition[1].center); 512 effect->u.condition[1].center);
522 if (param_err) return param_err; 513 if (param_err)
514 return param_err;
523 set_bit(FF_MOD2_IS_USED, core_effect->flags); 515 set_bit(FF_MOD2_IS_USED, core_effect->flags);
524 516
525 } 517 }
526 518
527 if (!is_update || need_core(iforce, effect)) { 519 if (!old || need_core(old, effect)) {
528 core_err = make_core(iforce, effect->id, 520 core_err = make_core(iforce, effect->id,
529 mod1_chunk->start, mod2_chunk->start, 521 mod1_chunk->start, mod2_chunk->start,
530 type, 0xc0, 522 type, 0xc0,
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index b4914e7231f8..24c684bc6337 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -83,103 +83,57 @@ static struct iforce_device iforce_device[] = {
83 { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce } 83 { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce }
84}; 84};
85 85
86 86static int iforce_playback(struct input_dev *dev, int effect_id, int value)
87
88static int iforce_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
89{ 87{
90 struct iforce* iforce = dev->private; 88 struct iforce* iforce = dev->private;
91 unsigned char data[3]; 89 struct iforce_core_effect *core_effect = &iforce->core_effects[effect_id];
92
93 if (type != EV_FF)
94 return -1;
95
96 switch (code) {
97
98 case FF_GAIN:
99
100 data[0] = value >> 9;
101 iforce_send_packet(iforce, FF_CMD_GAIN, data);
102
103 return 0;
104
105 case FF_AUTOCENTER:
106 90
107 data[0] = 0x03; 91 if (value > 0)
108 data[1] = value >> 9; 92 set_bit(FF_CORE_SHOULD_PLAY, core_effect->flags);
109 iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data); 93 else
94 clear_bit(FF_CORE_SHOULD_PLAY, core_effect->flags);
110 95
111 data[0] = 0x04; 96 iforce_control_playback(iforce, effect_id, value);
112 data[1] = 0x01; 97 return 0;
113 iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data); 98}
114 99
115 return 0; 100static void iforce_set_gain(struct input_dev *dev, u16 gain)
101{
102 struct iforce* iforce = dev->private;
103 unsigned char data[3];
116 104
117 default: /* Play or stop an effect */ 105 data[0] = gain >> 9;
106 iforce_send_packet(iforce, FF_CMD_GAIN, data);
107}
118 108
119 if (!CHECK_OWNERSHIP(code, iforce)) { 109static void iforce_set_autocenter(struct input_dev *dev, u16 magnitude)
120 return -1; 110{
121 } 111 struct iforce* iforce = dev->private;
122 if (value > 0) { 112 unsigned char data[3];
123 set_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[code].flags);
124 }
125 else {
126 clear_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[code].flags);
127 }
128 113
129 iforce_control_playback(iforce, code, value); 114 data[0] = 0x03;
130 return 0; 115 data[1] = magnitude >> 9;
131 } 116 iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
132 117
133 return -1; 118 data[0] = 0x04;
119 data[1] = 0x01;
120 iforce_send_packet(iforce, FF_CMD_AUTOCENTER, data);
134} 121}
135 122
136/* 123/*
137 * Function called when an ioctl is performed on the event dev entry. 124 * Function called when an ioctl is performed on the event dev entry.
138 * It uploads an effect to the device 125 * It uploads an effect to the device
139 */ 126 */
140static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect) 127static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old)
141{ 128{
142 struct iforce* iforce = dev->private; 129 struct iforce* iforce = dev->private;
143 int id; 130 struct iforce_core_effect *core_effect = &iforce->core_effects[effect->id];
144 int ret; 131 int ret;
145 int is_update;
146
147/* Check this effect type is supported by this device */
148 if (!test_bit(effect->type, iforce->dev->ffbit))
149 return -EINVAL;
150
151/*
152 * If we want to create a new effect, get a free id
153 */
154 if (effect->id == -1) {
155
156 for (id = 0; id < FF_EFFECTS_MAX; ++id)
157 if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags))
158 break;
159
160 if (id == FF_EFFECTS_MAX || id >= iforce->dev->ff_effects_max)
161 return -ENOMEM;
162
163 effect->id = id;
164 iforce->core_effects[id].owner = current->pid;
165 iforce->core_effects[id].flags[0] = (1 << FF_CORE_IS_USED); /* Only IS_USED bit must be set */
166
167 is_update = FALSE;
168 }
169 else {
170 /* We want to update an effect */
171 if (!CHECK_OWNERSHIP(effect->id, iforce))
172 return -EACCES;
173
174 /* Parameter type cannot be updated */
175 if (effect->type != iforce->core_effects[effect->id].effect.type)
176 return -EINVAL;
177 132
133 if (__test_and_set_bit(FF_CORE_IS_USED, core_effect->flags)) {
178 /* Check the effect is not already being updated */ 134 /* Check the effect is not already being updated */
179 if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags)) 135 if (test_bit(FF_CORE_UPDATE, core_effect->flags))
180 return -EAGAIN; 136 return -EAGAIN;
181
182 is_update = TRUE;
183 } 137 }
184 138
185/* 139/*
@@ -188,28 +142,28 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
188 switch (effect->type) { 142 switch (effect->type) {
189 143
190 case FF_PERIODIC: 144 case FF_PERIODIC:
191 ret = iforce_upload_periodic(iforce, effect, is_update); 145 ret = iforce_upload_periodic(iforce, effect, old);
192 break; 146 break;
193 147
194 case FF_CONSTANT: 148 case FF_CONSTANT:
195 ret = iforce_upload_constant(iforce, effect, is_update); 149 ret = iforce_upload_constant(iforce, effect, old);
196 break; 150 break;
197 151
198 case FF_SPRING: 152 case FF_SPRING:
199 case FF_DAMPER: 153 case FF_DAMPER:
200 ret = iforce_upload_condition(iforce, effect, is_update); 154 ret = iforce_upload_condition(iforce, effect, old);
201 break; 155 break;
202 156
203 default: 157 default:
204 return -EINVAL; 158 return -EINVAL;
205 } 159 }
160
206 if (ret == 0) { 161 if (ret == 0) {
207 /* A packet was sent, forbid new updates until we are notified 162 /* A packet was sent, forbid new updates until we are notified
208 * that the packet was updated 163 * that the packet was updated
209 */ 164 */
210 set_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags); 165 set_bit(FF_CORE_UPDATE, core_effect->flags);
211 } 166 }
212 iforce->core_effects[effect->id].effect = *effect;
213 return ret; 167 return ret;
214} 168}
215 169
@@ -219,20 +173,9 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
219 */ 173 */
220static int iforce_erase_effect(struct input_dev *dev, int effect_id) 174static int iforce_erase_effect(struct input_dev *dev, int effect_id)
221{ 175{
222 struct iforce* iforce = dev->private; 176 struct iforce *iforce = dev->private;
177 struct iforce_core_effect *core_effect = &iforce->core_effects[effect_id];
223 int err = 0; 178 int err = 0;
224 struct iforce_core_effect* core_effect;
225
226 if (effect_id < 0 || effect_id >= FF_EFFECTS_MAX)
227 return -EINVAL;
228
229 core_effect = &iforce->core_effects[effect_id];
230
231 /* Check who is trying to erase this effect */
232 if (core_effect->owner != current->pid) {
233 printk(KERN_WARNING "iforce-main.c: %d tried to erase an effect belonging to %d\n", current->pid, core_effect->owner);
234 return -EACCES;
235 }
236 179
237 if (test_bit(FF_MOD1_IS_USED, core_effect->flags)) 180 if (test_bit(FF_MOD1_IS_USED, core_effect->flags))
238 err = release_resource(&core_effect->mod1_chunk); 181 err = release_resource(&core_effect->mod1_chunk);
@@ -240,7 +183,7 @@ static int iforce_erase_effect(struct input_dev *dev, int effect_id)
240 if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags)) 183 if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags))
241 err = release_resource(&core_effect->mod2_chunk); 184 err = release_resource(&core_effect->mod2_chunk);
242 185
243 /*TODO: remember to change that if more FF_MOD* bits are added */ 186 /* TODO: remember to change that if more FF_MOD* bits are added */
244 core_effect->flags[0] = 0; 187 core_effect->flags[0] = 0;
245 188
246 return err; 189 return err;
@@ -260,52 +203,31 @@ static int iforce_open(struct input_dev *dev)
260#endif 203#endif
261 } 204 }
262 205
263 /* Enable force feedback */ 206 if (test_bit(EV_FF, dev->evbit)) {
264 iforce_send_packet(iforce, FF_CMD_ENABLE, "\004"); 207 /* Enable force feedback */
208 iforce_send_packet(iforce, FF_CMD_ENABLE, "\004");
209 }
265 210
266 return 0; 211 return 0;
267} 212}
268 213
269static int iforce_flush(struct input_dev *dev, struct file *file) 214static void iforce_release(struct input_dev *dev)
270{ 215{
271 struct iforce *iforce = dev->private; 216 struct iforce *iforce = dev->private;
272 int i; 217 int i;
273 218
274 /* Erase all effects this process owns */ 219 if (test_bit(EV_FF, dev->evbit)) {
275 for (i=0; i<dev->ff_effects_max; ++i) { 220 /* Check: no effects should be present in memory */
276 221 for (i = 0; i < dev->ff->max_effects; i++) {
277 if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) && 222 if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags)) {
278 current->pid == iforce->core_effects[i].owner) { 223 printk(KERN_WARNING "iforce_release: Device still owns effects\n");
279 224 break;
280 /* Stop effect */
281 input_report_ff(dev, i, 0);
282
283 /* Free ressources assigned to effect */
284 if (iforce_erase_effect(dev, i)) {
285 printk(KERN_WARNING "iforce_flush: erase effect %d failed\n", i);
286 } 225 }
287 } 226 }
288 227
228 /* Disable force feedback playback */
229 iforce_send_packet(iforce, FF_CMD_ENABLE, "\001");
289 } 230 }
290 return 0;
291}
292
293static void iforce_release(struct input_dev *dev)
294{
295 struct iforce *iforce = dev->private;
296 int i;
297
298 /* Check: no effect should be present in memory */
299 for (i=0; i<dev->ff_effects_max; ++i) {
300 if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags))
301 break;
302 }
303 if (i<dev->ff_effects_max) {
304 printk(KERN_WARNING "iforce_release: Device still owns effects\n");
305 }
306
307 /* Disable force feedback playback */
308 iforce_send_packet(iforce, FF_CMD_ENABLE, "\001");
309 231
310 switch (iforce->bus) { 232 switch (iforce->bus) {
311#ifdef CONFIG_JOYSTICK_IFORCE_USB 233#ifdef CONFIG_JOYSTICK_IFORCE_USB
@@ -342,8 +264,10 @@ void iforce_delete_device(struct iforce *iforce)
342int iforce_init_device(struct iforce *iforce) 264int iforce_init_device(struct iforce *iforce)
343{ 265{
344 struct input_dev *input_dev; 266 struct input_dev *input_dev;
267 struct ff_device *ff;
345 unsigned char c[] = "CEOV"; 268 unsigned char c[] = "CEOV";
346 int i; 269 int i, error;
270 int ff_effects = 0;
347 271
348 input_dev = input_allocate_device(); 272 input_dev = input_allocate_device();
349 if (!input_dev) 273 if (!input_dev)
@@ -378,11 +302,6 @@ int iforce_init_device(struct iforce *iforce)
378 input_dev->name = "Unknown I-Force device"; 302 input_dev->name = "Unknown I-Force device";
379 input_dev->open = iforce_open; 303 input_dev->open = iforce_open;
380 input_dev->close = iforce_release; 304 input_dev->close = iforce_release;
381 input_dev->flush = iforce_flush;
382 input_dev->event = iforce_input_event;
383 input_dev->upload_effect = iforce_upload_effect;
384 input_dev->erase_effect = iforce_erase_effect;
385 input_dev->ff_effects_max = 10;
386 305
387/* 306/*
388 * On-device memory allocation. 307 * On-device memory allocation.
@@ -430,15 +349,15 @@ int iforce_init_device(struct iforce *iforce)
430 printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n"); 349 printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n");
431 350
432 if (!iforce_get_id_packet(iforce, "N")) 351 if (!iforce_get_id_packet(iforce, "N"))
433 iforce->dev->ff_effects_max = iforce->edata[1]; 352 ff_effects = iforce->edata[1];
434 else 353 else
435 printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n"); 354 printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n");
436 355
437 /* Check if the device can store more effects than the driver can really handle */ 356 /* Check if the device can store more effects than the driver can really handle */
438 if (iforce->dev->ff_effects_max > FF_EFFECTS_MAX) { 357 if (ff_effects > IFORCE_EFFECTS_MAX) {
439 printk(KERN_WARNING "input??: Device can handle %d effects, but N_EFFECTS_MAX is set to %d in iforce.h\n", 358 printk(KERN_WARNING "iforce: Limiting number of effects to %d (device reports %d)\n",
440 iforce->dev->ff_effects_max, FF_EFFECTS_MAX); 359 IFORCE_EFFECTS_MAX, ff_effects);
441 iforce->dev->ff_effects_max = FF_EFFECTS_MAX; 360 ff_effects = IFORCE_EFFECTS_MAX;
442 } 361 }
443 362
444/* 363/*
@@ -472,12 +391,10 @@ int iforce_init_device(struct iforce *iforce)
472 * Set input device bitfields and ranges. 391 * Set input device bitfields and ranges.
473 */ 392 */
474 393
475 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS); 394 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF_STATUS);
476 395
477 for (i = 0; iforce->type->btn[i] >= 0; i++) { 396 for (i = 0; iforce->type->btn[i] >= 0; i++)
478 signed short t = iforce->type->btn[i]; 397 set_bit(iforce->type->btn[i], input_dev->keybit);
479 set_bit(t, input_dev->keybit);
480 }
481 set_bit(BTN_DEAD, input_dev->keybit); 398 set_bit(BTN_DEAD, input_dev->keybit);
482 399
483 for (i = 0; iforce->type->abs[i] >= 0; i++) { 400 for (i = 0; iforce->type->abs[i] >= 0; i++) {
@@ -516,9 +433,24 @@ int iforce_init_device(struct iforce *iforce)
516 } 433 }
517 } 434 }
518 435
519 for (i = 0; iforce->type->ff[i] >= 0; i++) 436 if (ff_effects) {
520 set_bit(iforce->type->ff[i], input_dev->ffbit);
521 437
438 for (i = 0; iforce->type->ff[i] >= 0; i++)
439 set_bit(iforce->type->ff[i], input_dev->ffbit);
440
441 error = input_ff_create(input_dev, ff_effects);
442 if (error) {
443 input_free_device(input_dev);
444 return error;
445 }
446
447 ff = input_dev->ff;
448 ff->upload = iforce_upload_effect;
449 ff->erase = iforce_erase_effect;
450 ff->set_gain = iforce_set_gain;
451 ff->set_autocenter = iforce_set_autocenter;
452 ff->playback = iforce_playback;
453 }
522/* 454/*
523 * Register input device. 455 * Register input device.
524 */ 456 */
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 76cb1f88f4e8..8632d47a7fbe 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -140,7 +140,10 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
140{ 140{
141 int i; 141 int i;
142 142
143 for (i = 0; i < iforce->dev->ff_effects_max; ++i) { 143 if (!iforce->dev->ff)
144 return 0;
145
146 for (i = 0; i < iforce->dev->ff->max_effects; ++i) {
144 if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) && 147 if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
145 (iforce->core_effects[i].mod1_chunk.start == addr || 148 (iforce->core_effects[i].mod1_chunk.start == addr ||
146 iforce->core_effects[i].mod2_chunk.start == addr)) { 149 iforce->core_effects[i].mod2_chunk.start == addr)) {
@@ -229,19 +232,17 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data,
229 i = data[1] & 0x7f; 232 i = data[1] & 0x7f;
230 if (data[1] & 0x80) { 233 if (data[1] & 0x80) {
231 if (!test_and_set_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) { 234 if (!test_and_set_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
232 /* Report play event */ 235 /* Report play event */
233 input_report_ff_status(dev, i, FF_STATUS_PLAYING); 236 input_report_ff_status(dev, i, FF_STATUS_PLAYING);
234 } 237 }
235 } 238 } else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
236 else if (test_and_clear_bit(FF_CORE_IS_PLAYED, iforce->core_effects[i].flags)) {
237 /* Report stop event */ 239 /* Report stop event */
238 input_report_ff_status(dev, i, FF_STATUS_STOPPED); 240 input_report_ff_status(dev, i, FF_STATUS_STOPPED);
239 } 241 }
240 if (LO(cmd) > 3) { 242 if (LO(cmd) > 3) {
241 int j; 243 int j;
242 for (j=3; j<LO(cmd); j+=2) { 244 for (j = 3; j < LO(cmd); j += 2)
243 mark_core_as_ready(iforce, data[j] | (data[j+1]<<8)); 245 mark_core_as_ready(iforce, data[j] | (data[j+1]<<8));
244 }
245 } 246 }
246 break; 247 break;
247 } 248 }
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index e9924d6f01b3..947df2739843 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -51,10 +51,7 @@
51#define IFORCE_232 1 51#define IFORCE_232 1
52#define IFORCE_USB 2 52#define IFORCE_USB 2
53 53
54#define FALSE 0 54#define IFORCE_EFFECTS_MAX 32
55#define TRUE 1
56
57#define FF_EFFECTS_MAX 32
58 55
59/* Each force feedback effect is made of one core effect, which can be 56/* Each force feedback effect is made of one core effect, which can be
60 * associated to at most to effect modifiers 57 * associated to at most to effect modifiers
@@ -67,24 +64,11 @@
67#define FF_CORE_UPDATE 5 /* Effect is being updated */ 64#define FF_CORE_UPDATE 5 /* Effect is being updated */
68#define FF_MODCORE_MAX 5 65#define FF_MODCORE_MAX 5
69 66
70#define CHECK_OWNERSHIP(i, iforce) \
71 ((i) < FF_EFFECTS_MAX && i >= 0 && \
72 test_bit(FF_CORE_IS_USED, (iforce)->core_effects[(i)].flags) && \
73 (current->pid == 0 || \
74 (iforce)->core_effects[(i)].owner == current->pid))
75
76struct iforce_core_effect { 67struct iforce_core_effect {
77 /* Information about where modifiers are stored in the device's memory */ 68 /* Information about where modifiers are stored in the device's memory */
78 struct resource mod1_chunk; 69 struct resource mod1_chunk;
79 struct resource mod2_chunk; 70 struct resource mod2_chunk;
80 unsigned long flags[NBITS(FF_MODCORE_MAX)]; 71 unsigned long flags[NBITS(FF_MODCORE_MAX)];
81 pid_t owner;
82 /* Used to keep track of parameters of an effect. They are needed
83 * to know what parts of an effect changed in an update operation.
84 * We try to send only parameter packets if possible, as sending
85 * effect parameter requires the effect to be stoped and restarted
86 */
87 struct ff_effect effect;
88}; 72};
89 73
90#define FF_CMD_EFFECT 0x010e 74#define FF_CMD_EFFECT 0x010e
@@ -145,7 +129,7 @@ struct iforce {
145 /* Force Feedback */ 129 /* Force Feedback */
146 wait_queue_head_t wait; 130 wait_queue_head_t wait;
147 struct resource device_memory; 131 struct resource device_memory;
148 struct iforce_core_effect core_effects[FF_EFFECTS_MAX]; 132 struct iforce_core_effect core_effects[IFORCE_EFFECTS_MAX];
149 struct mutex mem_mutex; 133 struct mutex mem_mutex;
150}; 134};
151 135
@@ -182,9 +166,9 @@ void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) ;
182int iforce_get_id_packet(struct iforce *iforce, char *packet); 166int iforce_get_id_packet(struct iforce *iforce, char *packet);
183 167
184/* iforce-ff.c */ 168/* iforce-ff.c */
185int iforce_upload_periodic(struct iforce*, struct ff_effect*, int is_update); 169int iforce_upload_periodic(struct iforce *, struct ff_effect *, struct ff_effect *);
186int iforce_upload_constant(struct iforce*, struct ff_effect*, int is_update); 170int iforce_upload_constant(struct iforce *, struct ff_effect *, struct ff_effect *);
187int iforce_upload_condition(struct iforce*, struct ff_effect*, int is_update); 171int iforce_upload_condition(struct iforce *, struct ff_effect *, struct ff_effect *);
188 172
189/* Public variables */ 173/* Public variables */
190extern struct serio_driver iforce_serio_drv; 174extern struct serio_driver iforce_serio_drv;