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; |
