0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "iforce.h"
0010
0011
0012
0013
0014
0015
0016
0017
0018 static int make_magnitude_modifier(struct iforce* iforce,
0019 struct resource* mod_chunk, int no_alloc, __s16 level)
0020 {
0021 unsigned char data[3];
0022
0023 if (!no_alloc) {
0024 mutex_lock(&iforce->mem_mutex);
0025 if (allocate_resource(&(iforce->device_memory), mod_chunk, 2,
0026 iforce->device_memory.start, iforce->device_memory.end, 2L,
0027 NULL, NULL)) {
0028 mutex_unlock(&iforce->mem_mutex);
0029 return -ENOSPC;
0030 }
0031 mutex_unlock(&iforce->mem_mutex);
0032 }
0033
0034 data[0] = LO(mod_chunk->start);
0035 data[1] = HI(mod_chunk->start);
0036 data[2] = HIFIX80(level);
0037
0038 iforce_send_packet(iforce, FF_CMD_MAGNITUDE, data);
0039
0040 iforce_dump_packet(iforce, "magnitude", FF_CMD_MAGNITUDE, data);
0041 return 0;
0042 }
0043
0044
0045
0046
0047
0048 static int make_period_modifier(struct iforce* iforce,
0049 struct resource* mod_chunk, int no_alloc,
0050 __s16 magnitude, __s16 offset, u16 period, u16 phase)
0051 {
0052 unsigned char data[7];
0053
0054 period = TIME_SCALE(period);
0055
0056 if (!no_alloc) {
0057 mutex_lock(&iforce->mem_mutex);
0058 if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0c,
0059 iforce->device_memory.start, iforce->device_memory.end, 2L,
0060 NULL, NULL)) {
0061 mutex_unlock(&iforce->mem_mutex);
0062 return -ENOSPC;
0063 }
0064 mutex_unlock(&iforce->mem_mutex);
0065 }
0066
0067 data[0] = LO(mod_chunk->start);
0068 data[1] = HI(mod_chunk->start);
0069
0070 data[2] = HIFIX80(magnitude);
0071 data[3] = HIFIX80(offset);
0072 data[4] = HI(phase);
0073
0074 data[5] = LO(period);
0075 data[6] = HI(period);
0076
0077 iforce_send_packet(iforce, FF_CMD_PERIOD, data);
0078
0079 return 0;
0080 }
0081
0082
0083
0084
0085
0086 static int make_envelope_modifier(struct iforce* iforce,
0087 struct resource* mod_chunk, int no_alloc,
0088 u16 attack_duration, __s16 initial_level,
0089 u16 fade_duration, __s16 final_level)
0090 {
0091 unsigned char data[8];
0092
0093 attack_duration = TIME_SCALE(attack_duration);
0094 fade_duration = TIME_SCALE(fade_duration);
0095
0096 if (!no_alloc) {
0097 mutex_lock(&iforce->mem_mutex);
0098 if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0e,
0099 iforce->device_memory.start, iforce->device_memory.end, 2L,
0100 NULL, NULL)) {
0101 mutex_unlock(&iforce->mem_mutex);
0102 return -ENOSPC;
0103 }
0104 mutex_unlock(&iforce->mem_mutex);
0105 }
0106
0107 data[0] = LO(mod_chunk->start);
0108 data[1] = HI(mod_chunk->start);
0109
0110 data[2] = LO(attack_duration);
0111 data[3] = HI(attack_duration);
0112 data[4] = HI(initial_level);
0113
0114 data[5] = LO(fade_duration);
0115 data[6] = HI(fade_duration);
0116 data[7] = HI(final_level);
0117
0118 iforce_send_packet(iforce, FF_CMD_ENVELOPE, data);
0119
0120 return 0;
0121 }
0122
0123
0124
0125
0126
0127 static int make_condition_modifier(struct iforce* iforce,
0128 struct resource* mod_chunk, int no_alloc,
0129 __u16 rsat, __u16 lsat, __s16 rk, __s16 lk, u16 db, __s16 center)
0130 {
0131 unsigned char data[10];
0132
0133 if (!no_alloc) {
0134 mutex_lock(&iforce->mem_mutex);
0135 if (allocate_resource(&(iforce->device_memory), mod_chunk, 8,
0136 iforce->device_memory.start, iforce->device_memory.end, 2L,
0137 NULL, NULL)) {
0138 mutex_unlock(&iforce->mem_mutex);
0139 return -ENOSPC;
0140 }
0141 mutex_unlock(&iforce->mem_mutex);
0142 }
0143
0144 data[0] = LO(mod_chunk->start);
0145 data[1] = HI(mod_chunk->start);
0146
0147 data[2] = (100 * rk) >> 15;
0148 data[3] = (100 * lk) >> 15;
0149
0150 center = (500 * center) >> 15;
0151 data[4] = LO(center);
0152 data[5] = HI(center);
0153
0154 db = (1000 * db) >> 16;
0155 data[6] = LO(db);
0156 data[7] = HI(db);
0157
0158 data[8] = (100 * rsat) >> 16;
0159 data[9] = (100 * lsat) >> 16;
0160
0161 iforce_send_packet(iforce, FF_CMD_CONDITION, data);
0162 iforce_dump_packet(iforce, "condition", FF_CMD_CONDITION, data);
0163
0164 return 0;
0165 }
0166
0167 static unsigned char find_button(struct iforce *iforce, signed short button)
0168 {
0169 int i;
0170
0171 for (i = 1; iforce->type->btn[i] >= 0; i++)
0172 if (iforce->type->btn[i] == button)
0173 return i + 1;
0174 return 0;
0175 }
0176
0177
0178
0179
0180
0181 static int need_condition_modifier(struct iforce *iforce,
0182 struct ff_effect *old,
0183 struct ff_effect *new)
0184 {
0185 int ret = 0;
0186 int i;
0187
0188 if (new->type != FF_SPRING && new->type != FF_FRICTION) {
0189 dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
0190 __func__);
0191 return 0;
0192 }
0193
0194 for (i = 0; i < 2; i++) {
0195 ret |= old->u.condition[i].right_saturation != new->u.condition[i].right_saturation
0196 || old->u.condition[i].left_saturation != new->u.condition[i].left_saturation
0197 || old->u.condition[i].right_coeff != new->u.condition[i].right_coeff
0198 || old->u.condition[i].left_coeff != new->u.condition[i].left_coeff
0199 || old->u.condition[i].deadband != new->u.condition[i].deadband
0200 || old->u.condition[i].center != new->u.condition[i].center;
0201 }
0202 return ret;
0203 }
0204
0205
0206
0207
0208
0209 static int need_magnitude_modifier(struct iforce *iforce,
0210 struct ff_effect *old,
0211 struct ff_effect *effect)
0212 {
0213 if (effect->type != FF_CONSTANT) {
0214 dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
0215 __func__);
0216 return 0;
0217 }
0218
0219 return old->u.constant.level != effect->u.constant.level;
0220 }
0221
0222
0223
0224
0225
0226 static int need_envelope_modifier(struct iforce *iforce, struct ff_effect *old,
0227 struct ff_effect *effect)
0228 {
0229 switch (effect->type) {
0230 case FF_CONSTANT:
0231 if (old->u.constant.envelope.attack_length != effect->u.constant.envelope.attack_length
0232 || old->u.constant.envelope.attack_level != effect->u.constant.envelope.attack_level
0233 || old->u.constant.envelope.fade_length != effect->u.constant.envelope.fade_length
0234 || old->u.constant.envelope.fade_level != effect->u.constant.envelope.fade_level)
0235 return 1;
0236 break;
0237
0238 case FF_PERIODIC:
0239 if (old->u.periodic.envelope.attack_length != effect->u.periodic.envelope.attack_length
0240 || old->u.periodic.envelope.attack_level != effect->u.periodic.envelope.attack_level
0241 || old->u.periodic.envelope.fade_length != effect->u.periodic.envelope.fade_length
0242 || old->u.periodic.envelope.fade_level != effect->u.periodic.envelope.fade_level)
0243 return 1;
0244 break;
0245
0246 default:
0247 dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
0248 __func__);
0249 }
0250
0251 return 0;
0252 }
0253
0254
0255
0256
0257
0258 static int need_period_modifier(struct iforce *iforce, struct ff_effect *old,
0259 struct ff_effect *new)
0260 {
0261 if (new->type != FF_PERIODIC) {
0262 dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
0263 __func__);
0264 return 0;
0265 }
0266 return (old->u.periodic.period != new->u.periodic.period
0267 || old->u.periodic.magnitude != new->u.periodic.magnitude
0268 || old->u.periodic.offset != new->u.periodic.offset
0269 || old->u.periodic.phase != new->u.periodic.phase);
0270 }
0271
0272
0273
0274
0275
0276 static int need_core(struct ff_effect *old, struct ff_effect *new)
0277 {
0278 if (old->direction != new->direction
0279 || old->trigger.button != new->trigger.button
0280 || old->trigger.interval != new->trigger.interval
0281 || old->replay.length != new->replay.length
0282 || old->replay.delay != new->replay.delay)
0283 return 1;
0284
0285 return 0;
0286 }
0287
0288
0289
0290 static int make_core(struct iforce* iforce, u16 id, u16 mod_id1, u16 mod_id2,
0291 u8 effect_type, u8 axes, u16 duration, u16 delay, u16 button,
0292 u16 interval, u16 direction)
0293 {
0294 unsigned char data[14];
0295
0296 duration = TIME_SCALE(duration);
0297 delay = TIME_SCALE(delay);
0298 interval = TIME_SCALE(interval);
0299
0300 data[0] = LO(id);
0301 data[1] = effect_type;
0302 data[2] = LO(axes) | find_button(iforce, button);
0303
0304 data[3] = LO(duration);
0305 data[4] = HI(duration);
0306
0307 data[5] = HI(direction);
0308
0309 data[6] = LO(interval);
0310 data[7] = HI(interval);
0311
0312 data[8] = LO(mod_id1);
0313 data[9] = HI(mod_id1);
0314 data[10] = LO(mod_id2);
0315 data[11] = HI(mod_id2);
0316
0317 data[12] = LO(delay);
0318 data[13] = HI(delay);
0319
0320
0321
0322
0323 iforce_send_packet(iforce, FF_CMD_EFFECT, data);
0324
0325
0326 if (test_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[id].flags)) {
0327
0328 iforce_control_playback(iforce, id, 1);
0329 }
0330
0331 return 0;
0332 }
0333
0334
0335
0336
0337
0338 int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
0339 {
0340 u8 wave_code;
0341 int core_id = effect->id;
0342 struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
0343 struct resource* mod1_chunk = &(iforce->core_effects[core_id].mod1_chunk);
0344 struct resource* mod2_chunk = &(iforce->core_effects[core_id].mod2_chunk);
0345 int param1_err = 1;
0346 int param2_err = 1;
0347 int core_err = 0;
0348
0349 if (!old || need_period_modifier(iforce, old, effect)) {
0350 param1_err = make_period_modifier(iforce, mod1_chunk,
0351 old != NULL,
0352 effect->u.periodic.magnitude, effect->u.periodic.offset,
0353 effect->u.periodic.period, effect->u.periodic.phase);
0354 if (param1_err)
0355 return param1_err;
0356 set_bit(FF_MOD1_IS_USED, core_effect->flags);
0357 }
0358
0359 if (!old || need_envelope_modifier(iforce, old, effect)) {
0360 param2_err = make_envelope_modifier(iforce, mod2_chunk,
0361 old !=NULL,
0362 effect->u.periodic.envelope.attack_length,
0363 effect->u.periodic.envelope.attack_level,
0364 effect->u.periodic.envelope.fade_length,
0365 effect->u.periodic.envelope.fade_level);
0366 if (param2_err)
0367 return param2_err;
0368 set_bit(FF_MOD2_IS_USED, core_effect->flags);
0369 }
0370
0371 switch (effect->u.periodic.waveform) {
0372 case FF_SQUARE: wave_code = 0x20; break;
0373 case FF_TRIANGLE: wave_code = 0x21; break;
0374 case FF_SINE: wave_code = 0x22; break;
0375 case FF_SAW_UP: wave_code = 0x23; break;
0376 case FF_SAW_DOWN: wave_code = 0x24; break;
0377 default: wave_code = 0x20; break;
0378 }
0379
0380 if (!old || need_core(old, effect)) {
0381 core_err = make_core(iforce, effect->id,
0382 mod1_chunk->start,
0383 mod2_chunk->start,
0384 wave_code,
0385 0x20,
0386 effect->replay.length,
0387 effect->replay.delay,
0388 effect->trigger.button,
0389 effect->trigger.interval,
0390 effect->direction);
0391 }
0392
0393
0394
0395
0396
0397
0398
0399 return core_err < 0 ? core_err : (param1_err && param2_err);
0400 }
0401
0402
0403
0404
0405
0406
0407
0408
0409 int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
0410 {
0411 int core_id = effect->id;
0412 struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
0413 struct resource* mod1_chunk = &(iforce->core_effects[core_id].mod1_chunk);
0414 struct resource* mod2_chunk = &(iforce->core_effects[core_id].mod2_chunk);
0415 int param1_err = 1;
0416 int param2_err = 1;
0417 int core_err = 0;
0418
0419 if (!old || need_magnitude_modifier(iforce, old, effect)) {
0420 param1_err = make_magnitude_modifier(iforce, mod1_chunk,
0421 old != NULL,
0422 effect->u.constant.level);
0423 if (param1_err)
0424 return param1_err;
0425 set_bit(FF_MOD1_IS_USED, core_effect->flags);
0426 }
0427
0428 if (!old || need_envelope_modifier(iforce, old, effect)) {
0429 param2_err = make_envelope_modifier(iforce, mod2_chunk,
0430 old != NULL,
0431 effect->u.constant.envelope.attack_length,
0432 effect->u.constant.envelope.attack_level,
0433 effect->u.constant.envelope.fade_length,
0434 effect->u.constant.envelope.fade_level);
0435 if (param2_err)
0436 return param2_err;
0437 set_bit(FF_MOD2_IS_USED, core_effect->flags);
0438 }
0439
0440 if (!old || need_core(old, effect)) {
0441 core_err = make_core(iforce, effect->id,
0442 mod1_chunk->start,
0443 mod2_chunk->start,
0444 0x00,
0445 0x20,
0446 effect->replay.length,
0447 effect->replay.delay,
0448 effect->trigger.button,
0449 effect->trigger.interval,
0450 effect->direction);
0451 }
0452
0453
0454
0455
0456
0457
0458
0459 return core_err < 0 ? core_err : (param1_err && param2_err);
0460 }
0461
0462
0463
0464
0465 int iforce_upload_condition(struct iforce *iforce, struct ff_effect *effect, struct ff_effect *old)
0466 {
0467 int core_id = effect->id;
0468 struct iforce_core_effect* core_effect = iforce->core_effects + core_id;
0469 struct resource* mod1_chunk = &(core_effect->mod1_chunk);
0470 struct resource* mod2_chunk = &(core_effect->mod2_chunk);
0471 u8 type;
0472 int param_err = 1;
0473 int core_err = 0;
0474
0475 switch (effect->type) {
0476 case FF_SPRING: type = 0x40; break;
0477 case FF_DAMPER: type = 0x41; break;
0478 default: return -1;
0479 }
0480
0481 if (!old || need_condition_modifier(iforce, old, effect)) {
0482 param_err = make_condition_modifier(iforce, mod1_chunk,
0483 old != NULL,
0484 effect->u.condition[0].right_saturation,
0485 effect->u.condition[0].left_saturation,
0486 effect->u.condition[0].right_coeff,
0487 effect->u.condition[0].left_coeff,
0488 effect->u.condition[0].deadband,
0489 effect->u.condition[0].center);
0490 if (param_err)
0491 return param_err;
0492 set_bit(FF_MOD1_IS_USED, core_effect->flags);
0493
0494 param_err = make_condition_modifier(iforce, mod2_chunk,
0495 old != NULL,
0496 effect->u.condition[1].right_saturation,
0497 effect->u.condition[1].left_saturation,
0498 effect->u.condition[1].right_coeff,
0499 effect->u.condition[1].left_coeff,
0500 effect->u.condition[1].deadband,
0501 effect->u.condition[1].center);
0502 if (param_err)
0503 return param_err;
0504 set_bit(FF_MOD2_IS_USED, core_effect->flags);
0505
0506 }
0507
0508 if (!old || need_core(old, effect)) {
0509 core_err = make_core(iforce, effect->id,
0510 mod1_chunk->start, mod2_chunk->start,
0511 type, 0xc0,
0512 effect->replay.length, effect->replay.delay,
0513 effect->trigger.button, effect->trigger.interval,
0514 effect->direction);
0515 }
0516
0517
0518
0519
0520
0521
0522
0523 return core_err < 0 ? core_err : param_err;
0524 }