in usbhid/hid-pidff.c [552:705]
static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
struct ff_effect *old)
{
struct pidff_device *pidff = dev->ff->private;
int type_id;
int error;
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0;
if (old) {
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] =
pidff->pid_id[effect->id];
}
switch (effect->type) {
case FF_CONSTANT:
if (!old) {
error = pidff_request_effect_upload(pidff,
pidff->type_id[PID_CONSTANT]);
if (error)
return error;
}
if (!old || pidff_needs_set_effect(effect, old))
pidff_set_effect_report(pidff, effect);
if (!old || pidff_needs_set_constant(effect, old))
pidff_set_constant_force_report(pidff, effect);
if (!old ||
pidff_needs_set_envelope(&effect->u.constant.envelope,
&old->u.constant.envelope))
pidff_set_envelope_report(pidff,
&effect->u.constant.envelope);
break;
case FF_PERIODIC:
if (!old) {
switch (effect->u.periodic.waveform) {
case FF_SQUARE:
type_id = PID_SQUARE;
break;
case FF_TRIANGLE:
type_id = PID_TRIANGLE;
break;
case FF_SINE:
type_id = PID_SINE;
break;
case FF_SAW_UP:
type_id = PID_SAW_UP;
break;
case FF_SAW_DOWN:
type_id = PID_SAW_DOWN;
break;
default:
hid_err(pidff->hid, "invalid waveform\n");
return -EINVAL;
}
error = pidff_request_effect_upload(pidff,
pidff->type_id[type_id]);
if (error)
return error;
}
if (!old || pidff_needs_set_effect(effect, old))
pidff_set_effect_report(pidff, effect);
if (!old || pidff_needs_set_periodic(effect, old))
pidff_set_periodic_report(pidff, effect);
if (!old ||
pidff_needs_set_envelope(&effect->u.periodic.envelope,
&old->u.periodic.envelope))
pidff_set_envelope_report(pidff,
&effect->u.periodic.envelope);
break;
case FF_RAMP:
if (!old) {
error = pidff_request_effect_upload(pidff,
pidff->type_id[PID_RAMP]);
if (error)
return error;
}
if (!old || pidff_needs_set_effect(effect, old))
pidff_set_effect_report(pidff, effect);
if (!old || pidff_needs_set_ramp(effect, old))
pidff_set_ramp_force_report(pidff, effect);
if (!old ||
pidff_needs_set_envelope(&effect->u.ramp.envelope,
&old->u.ramp.envelope))
pidff_set_envelope_report(pidff,
&effect->u.ramp.envelope);
break;
case FF_SPRING:
if (!old) {
error = pidff_request_effect_upload(pidff,
pidff->type_id[PID_SPRING]);
if (error)
return error;
}
if (!old || pidff_needs_set_effect(effect, old))
pidff_set_effect_report(pidff, effect);
if (!old || pidff_needs_set_condition(effect, old))
pidff_set_condition_report(pidff, effect);
break;
case FF_FRICTION:
if (!old) {
error = pidff_request_effect_upload(pidff,
pidff->type_id[PID_FRICTION]);
if (error)
return error;
}
if (!old || pidff_needs_set_effect(effect, old))
pidff_set_effect_report(pidff, effect);
if (!old || pidff_needs_set_condition(effect, old))
pidff_set_condition_report(pidff, effect);
break;
case FF_DAMPER:
if (!old) {
error = pidff_request_effect_upload(pidff,
pidff->type_id[PID_DAMPER]);
if (error)
return error;
}
if (!old || pidff_needs_set_effect(effect, old))
pidff_set_effect_report(pidff, effect);
if (!old || pidff_needs_set_condition(effect, old))
pidff_set_condition_report(pidff, effect);
break;
case FF_INERTIA:
if (!old) {
error = pidff_request_effect_upload(pidff,
pidff->type_id[PID_INERTIA]);
if (error)
return error;
}
if (!old || pidff_needs_set_effect(effect, old))
pidff_set_effect_report(pidff, effect);
if (!old || pidff_needs_set_condition(effect, old))
pidff_set_condition_report(pidff, effect);
break;
default:
hid_err(pidff->hid, "invalid type\n");
return -EINVAL;
}
if (!old)
pidff->pid_id[effect->id] =
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
hid_dbg(pidff->hid, "uploaded\n");
return 0;
}