Skip to content

Commit 7fbaa03

Browse files
LawstorantJiri Kosina
authored andcommitted
HID: pidff: Rework pidff_upload_effect
One of the more complicated functions. Expunge some of the logic to separate functions (FF -> PID id conversion) Add a macro for envelope check to make it more readable in the upload function. All this made it possible to to expunge common code from the big switch statement and reduce the overall function size considerably. Now it can fit on one screen. Move the effect_cout logic from report functions to upload/erase functions. Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
1 parent 1abfcd8 commit 7fbaa03

1 file changed

Lines changed: 115 additions & 128 deletions

File tree

drivers/hid/usbhid/hid-pidff.c

Lines changed: 115 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ static const u8 pidff_effect_types[] = {
142142
#define PID_BLOCK_LOAD_SUCCESS 0
143143
#define PID_BLOCK_LOAD_FULL 1
144144
#define PID_BLOCK_LOAD_ERROR 2
145-
static const u8 pidff_block_load_status[] = { 0x8c, 0x8d, 0x8e};
145+
static const u8 pidff_block_load_status[] = { 0x8c, 0x8d, 0x8e };
146146

147147
#define PID_EFFECT_START 0
148148
#define PID_EFFECT_STOP 1
@@ -242,6 +242,62 @@ static int pidff_is_effect_conditional(struct ff_effect *effect)
242242
effect->type == FF_FRICTION;
243243
}
244244

245+
/*
246+
* Get PID effect index from FF effect type.
247+
* Return 0 if invalid.
248+
*/
249+
static int pidff_effect_ff_to_pid(struct ff_effect *effect)
250+
{
251+
switch (effect->type) {
252+
case FF_CONSTANT:
253+
return PID_CONSTANT;
254+
case FF_RAMP:
255+
return PID_RAMP;
256+
case FF_SPRING:
257+
return PID_SPRING;
258+
case FF_DAMPER:
259+
return PID_DAMPER;
260+
case FF_INERTIA:
261+
return PID_INERTIA;
262+
case FF_FRICTION:
263+
return PID_FRICTION;
264+
case FF_PERIODIC:
265+
switch (effect->u.periodic.waveform) {
266+
case FF_SQUARE:
267+
return PID_SQUARE;
268+
case FF_TRIANGLE:
269+
return PID_TRIANGLE;
270+
case FF_SINE:
271+
return PID_SINE;
272+
case FF_SAW_UP:
273+
return PID_SAW_UP;
274+
case FF_SAW_DOWN:
275+
return PID_SAW_DOWN;
276+
}
277+
}
278+
pr_err("invalid effect type\n");
279+
return -EINVAL;
280+
}
281+
282+
/*
283+
* Get effect id in the device descriptor.
284+
* Return 0 if invalid.
285+
*/
286+
static int pidff_get_effect_type_id(struct pidff_device *pidff,
287+
struct ff_effect *effect)
288+
{
289+
int id = pidff_effect_ff_to_pid(effect);
290+
291+
if (id < 0)
292+
return 0;
293+
294+
if (effect->type == FF_PERIODIC &&
295+
pidff->quirks & HID_PIDFF_QUIRK_PERIODIC_SINE_ONLY)
296+
id = PID_SINE;
297+
298+
return pidff->type_id[id];
299+
}
300+
245301
/*
246302
* Clamp value for a given field
247303
*/
@@ -387,12 +443,12 @@ static void pidff_set_envelope_report(struct pidff_device *pidff,
387443
pidff->set_envelope[PID_FADE_LEVEL].field);
388444

389445
pidff_set_time(&pidff->set_envelope[PID_ATTACK_TIME],
390-
envelope->attack_length);
446+
envelope->attack_length);
391447
pidff_set_time(&pidff->set_envelope[PID_FADE_TIME],
392-
envelope->fade_length);
448+
envelope->fade_length);
393449

394450
hid_hw_request(pidff->hid, pidff->reports[PID_SET_ENVELOPE],
395-
HID_REQ_SET_REPORT);
451+
HID_REQ_SET_REPORT);
396452
}
397453

398454
/*
@@ -401,16 +457,15 @@ static void pidff_set_envelope_report(struct pidff_device *pidff,
401457
static int pidff_needs_set_envelope(struct ff_envelope *envelope,
402458
struct ff_envelope *old)
403459
{
404-
bool needs_new_envelope;
460+
int needs_new_envelope;
405461

406462
needs_new_envelope = envelope->attack_level != 0 ||
407463
envelope->fade_level != 0 ||
408464
envelope->attack_length != 0 ||
409465
envelope->fade_length != 0;
410466

411467
if (!needs_new_envelope)
412-
return false;
413-
468+
return 0;
414469
if (!old)
415470
return needs_new_envelope;
416471

@@ -423,16 +478,16 @@ static int pidff_needs_set_envelope(struct ff_envelope *envelope,
423478
/*
424479
* Send constant force report to the device
425480
*/
426-
static void pidff_set_constant_force_report(struct pidff_device *pidff,
427-
struct ff_effect *effect)
481+
static void pidff_set_constant_report(struct pidff_device *pidff,
482+
struct ff_effect *effect)
428483
{
429484
pidff->set_constant[PID_EFFECT_BLOCK_INDEX].value[0] =
430485
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
431486
pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE],
432487
effect->u.constant.level);
433488

434489
hid_hw_request(pidff->hid, pidff->reports[PID_SET_CONSTANT],
435-
HID_REQ_SET_REPORT);
490+
HID_REQ_SET_REPORT);
436491
}
437492

438493
/*
@@ -583,8 +638,8 @@ static int pidff_needs_set_condition(struct ff_effect *effect,
583638
/*
584639
* Send ramp force report to the device
585640
*/
586-
static void pidff_set_ramp_force_report(struct pidff_device *pidff,
587-
struct ff_effect *effect)
641+
static void pidff_set_ramp_report(struct pidff_device *pidff,
642+
struct ff_effect *effect)
588643
{
589644
pidff->set_ramp[PID_EFFECT_BLOCK_INDEX].value[0] =
590645
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
@@ -593,7 +648,7 @@ static void pidff_set_ramp_force_report(struct pidff_device *pidff,
593648
pidff_set_signed(&pidff->set_ramp[PID_RAMP_END],
594649
effect->u.ramp.end_level);
595650
hid_hw_request(pidff->hid, pidff->reports[PID_SET_RAMP],
596-
HID_REQ_SET_REPORT);
651+
HID_REQ_SET_REPORT);
597652
}
598653

599654
/*
@@ -703,9 +758,6 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
703758
{
704759
int j;
705760

706-
if (!pidff->effect_count)
707-
pidff_reset(pidff);
708-
709761
pidff->create_new_effect_type->value[0] = efnum;
710762
hid_hw_request(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT],
711763
HID_REQ_SET_REPORT);
@@ -725,8 +777,6 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
725777
hid_dbg(pidff->hid, "device reported free memory: %d bytes\n",
726778
pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
727779
pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
728-
729-
pidff->effect_count++;
730780
return 0;
731781
}
732782
if (pidff->block_load_status->value[0] ==
@@ -767,7 +817,7 @@ static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n)
767817
}
768818

769819
hid_hw_request(pidff->hid, pidff->reports[PID_EFFECT_OPERATION],
770-
HID_REQ_SET_REPORT);
820+
HID_REQ_SET_REPORT);
771821
}
772822

773823
/*
@@ -791,10 +841,7 @@ static void pidff_erase_pid(struct pidff_device *pidff, int pid_id)
791841
{
792842
pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
793843
hid_hw_request(pidff->hid, pidff->reports[PID_BLOCK_FREE],
794-
HID_REQ_SET_REPORT);
795-
796-
if (pidff->effect_count > 0)
797-
pidff->effect_count--;
844+
HID_REQ_SET_REPORT);
798845
}
799846

800847
/*
@@ -816,139 +863,79 @@ static int pidff_erase_effect(struct input_dev *dev, int effect_id)
816863
pidff_playback_pid(pidff, pid_id, 0);
817864
pidff_erase_pid(pidff, pid_id);
818865

866+
if (pidff->effect_count > 0)
867+
pidff->effect_count--;
868+
869+
hid_dbg(pidff->hid, "current effect count: %d", pidff->effect_count);
819870
return 0;
820871
}
821872

873+
#define PIDFF_SET_REPORT_IF_NEEDED(type, effect, old) \
874+
({ if (!old || pidff_needs_set_## type(effect, old)) \
875+
pidff_set_ ##type## _report(pidff, effect); })
876+
877+
#define PIDFF_SET_ENVELOPE_IF_NEEDED(type, effect, old) \
878+
({ if (pidff_needs_set_envelope(&effect->u.type.envelope, \
879+
old ? &old->u.type.envelope : NULL)) \
880+
pidff_set_envelope_report(pidff, &effect->u.type.envelope); })
881+
822882
/*
823883
* Effect upload handler
824884
*/
825-
static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
885+
static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *new,
826886
struct ff_effect *old)
827887
{
828888
struct pidff_device *pidff = dev->ff->private;
829-
int type_id;
830-
int error;
889+
const int type_id = pidff_get_effect_type_id(pidff, new);
831890

832-
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0;
833-
if (old) {
834-
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] =
835-
pidff->pid_id[effect->id];
891+
if (!type_id) {
892+
hid_err(pidff->hid, "effect type not supported\n");
893+
return -EINVAL;
836894
}
837895

838-
switch (effect->type) {
896+
if (!pidff->effect_count)
897+
pidff_reset(pidff);
898+
899+
if (!old) {
900+
int error = pidff_request_effect_upload(pidff, type_id);
901+
902+
if (error)
903+
return error;
904+
905+
pidff->effect_count++;
906+
hid_dbg(pidff->hid, "current effect count: %d", pidff->effect_count);
907+
pidff->pid_id[new->id] =
908+
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
909+
}
910+
911+
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] =
912+
pidff->pid_id[new->id];
913+
914+
PIDFF_SET_REPORT_IF_NEEDED(effect, new, old);
915+
switch (new->type) {
839916
case FF_CONSTANT:
840-
if (!old) {
841-
error = pidff_request_effect_upload(pidff,
842-
pidff->type_id[PID_CONSTANT]);
843-
if (error)
844-
return error;
845-
}
846-
if (!old || pidff_needs_set_effect(effect, old))
847-
pidff_set_effect_report(pidff, effect);
848-
if (!old || pidff_needs_set_constant(effect, old))
849-
pidff_set_constant_force_report(pidff, effect);
850-
if (pidff_needs_set_envelope(&effect->u.constant.envelope,
851-
old ? &old->u.constant.envelope : NULL))
852-
pidff_set_envelope_report(pidff, &effect->u.constant.envelope);
917+
PIDFF_SET_REPORT_IF_NEEDED(constant, new, old);
918+
PIDFF_SET_ENVELOPE_IF_NEEDED(constant, new, old);
853919
break;
854920

855921
case FF_PERIODIC:
856-
if (!old) {
857-
switch (effect->u.periodic.waveform) {
858-
case FF_SQUARE:
859-
type_id = PID_SQUARE;
860-
break;
861-
case FF_TRIANGLE:
862-
type_id = PID_TRIANGLE;
863-
break;
864-
case FF_SINE:
865-
type_id = PID_SINE;
866-
break;
867-
case FF_SAW_UP:
868-
type_id = PID_SAW_UP;
869-
break;
870-
case FF_SAW_DOWN:
871-
type_id = PID_SAW_DOWN;
872-
break;
873-
default:
874-
hid_err(pidff->hid, "invalid waveform\n");
875-
return -EINVAL;
876-
}
877-
878-
if (pidff->quirks & HID_PIDFF_QUIRK_PERIODIC_SINE_ONLY)
879-
type_id = PID_SINE;
880-
881-
error = pidff_request_effect_upload(pidff,
882-
pidff->type_id[type_id]);
883-
if (error)
884-
return error;
885-
}
886-
if (!old || pidff_needs_set_effect(effect, old))
887-
pidff_set_effect_report(pidff, effect);
888-
if (!old || pidff_needs_set_periodic(effect, old))
889-
pidff_set_periodic_report(pidff, effect);
890-
if (pidff_needs_set_envelope(&effect->u.periodic.envelope,
891-
old ? &old->u.periodic.envelope : NULL))
892-
pidff_set_envelope_report(pidff, &effect->u.periodic.envelope);
922+
PIDFF_SET_REPORT_IF_NEEDED(periodic, new, old);
923+
PIDFF_SET_ENVELOPE_IF_NEEDED(periodic, new, old);
893924
break;
894925

895926
case FF_RAMP:
896-
if (!old) {
897-
error = pidff_request_effect_upload(pidff,
898-
pidff->type_id[PID_RAMP]);
899-
if (error)
900-
return error;
901-
}
902-
if (!old || pidff_needs_set_effect(effect, old))
903-
pidff_set_effect_report(pidff, effect);
904-
if (!old || pidff_needs_set_ramp(effect, old))
905-
pidff_set_ramp_force_report(pidff, effect);
906-
if (pidff_needs_set_envelope(&effect->u.ramp.envelope,
907-
old ? &old->u.ramp.envelope : NULL))
908-
pidff_set_envelope_report(pidff, &effect->u.ramp.envelope);
927+
PIDFF_SET_REPORT_IF_NEEDED(ramp, new, old);
928+
PIDFF_SET_ENVELOPE_IF_NEEDED(ramp, new, old);
909929
break;
910930

911931
case FF_SPRING:
912932
case FF_DAMPER:
913933
case FF_INERTIA:
914934
case FF_FRICTION:
915-
if (!old) {
916-
switch (effect->type) {
917-
case FF_SPRING:
918-
type_id = PID_SPRING;
919-
break;
920-
case FF_DAMPER:
921-
type_id = PID_DAMPER;
922-
break;
923-
case FF_INERTIA:
924-
type_id = PID_INERTIA;
925-
break;
926-
case FF_FRICTION:
927-
type_id = PID_FRICTION;
928-
break;
929-
}
930-
error = pidff_request_effect_upload(pidff,
931-
pidff->type_id[type_id]);
932-
if (error)
933-
return error;
934-
}
935-
if (!old || pidff_needs_set_effect(effect, old))
936-
pidff_set_effect_report(pidff, effect);
937-
if (!old || pidff_needs_set_condition(effect, old))
938-
pidff_set_condition_report(pidff, effect);
935+
PIDFF_SET_REPORT_IF_NEEDED(condition, new, old);
939936
break;
940-
941-
default:
942-
hid_err(pidff->hid, "invalid type\n");
943-
return -EINVAL;
944937
}
945-
946-
if (!old)
947-
pidff->pid_id[effect->id] =
948-
pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
949-
950938
hid_dbg(pidff->hid, "uploaded\n");
951-
952939
return 0;
953940
}
954941

0 commit comments

Comments
 (0)