diff options
author | Anssi Hannula <anssi.hannula@gmail.com> | 2006-07-19 01:40:39 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2006-07-19 01:40:39 -0400 |
commit | f6a01c85965c9e6fa8fb893c1fa5db16130d0ccb (patch) | |
tree | d23d6607c6167109cffb203e8b427824c979af94 | |
parent | 7d928a2b14eede1f333db7b7b684c57f7fa7f456 (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.c | 118 | ||||
-rw-r--r-- | drivers/input/joystick/iforce/iforce-main.c | 226 | ||||
-rw-r--r-- | drivers/input/joystick/iforce/iforce-packets.c | 15 | ||||
-rw-r--r-- | drivers/input/joystick/iforce/iforce.h | 26 |
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, | |||
188 | static unsigned char find_button(struct iforce *iforce, signed short button) | 188 | static 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 | */ |
201 | static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new) | 202 | static 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 | */ |
228 | static int need_magnitude_modifier(struct iforce* iforce, struct ff_effect* effect) | 227 | static 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 | */ |
245 | static int need_envelope_modifier(struct iforce* iforce, struct ff_effect* effect) | 241 | static 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 | */ |
278 | static int need_period_modifier(struct iforce* iforce, struct ff_effect* new) | 271 | static 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 | */ |
298 | static int need_core(struct iforce* iforce, struct ff_effect* new) | 287 | static 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 | */ |
363 | int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int is_update) | 349 | int 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 | */ |
432 | int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int is_update) | 420 | int 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 | */ |
486 | int iforce_upload_condition(struct iforce* iforce, struct ff_effect* effect, int is_update) | 476 | int 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 | 86 | static int iforce_playback(struct input_dev *dev, int effect_id, int value) | |
87 | |||
88 | static 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; | 100 | static 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)) { | 109 | static 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 | */ |
140 | static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect) | 127 | static 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 | */ |
220 | static int iforce_erase_effect(struct input_dev *dev, int effect_id) | 174 | static 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 | ||
269 | static int iforce_flush(struct input_dev *dev, struct file *file) | 214 | static 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 | |||
293 | static 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) | |||
342 | int iforce_init_device(struct iforce *iforce) | 264 | int 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 | |||
76 | struct iforce_core_effect { | 67 | struct 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) ; | |||
182 | int iforce_get_id_packet(struct iforce *iforce, char *packet); | 166 | int iforce_get_id_packet(struct iforce *iforce, char *packet); |
183 | 167 | ||
184 | /* iforce-ff.c */ | 168 | /* iforce-ff.c */ |
185 | int iforce_upload_periodic(struct iforce*, struct ff_effect*, int is_update); | 169 | int iforce_upload_periodic(struct iforce *, struct ff_effect *, struct ff_effect *); |
186 | int iforce_upload_constant(struct iforce*, struct ff_effect*, int is_update); | 170 | int iforce_upload_constant(struct iforce *, struct ff_effect *, struct ff_effect *); |
187 | int iforce_upload_condition(struct iforce*, struct ff_effect*, int is_update); | 171 | int iforce_upload_condition(struct iforce *, struct ff_effect *, struct ff_effect *); |
188 | 172 | ||
189 | /* Public variables */ | 173 | /* Public variables */ |
190 | extern struct serio_driver iforce_serio_drv; | 174 | extern struct serio_driver iforce_serio_drv; |