Skip to content

Commit cb3fd78

Browse files
LawstorantJiri Kosina
authored andcommitted
HID: pidff: Completely rework and fix pidff_reset function
Previously, it was assumed that DEVICE_CONTROL usage is always an array but a lot of devices implements it as a bitmask variable. This led to the pidff_reset function not working and causing errors in such cases. Selectors can come in three types. One selection of a set, N selections and Any selection in form of bitmask as from USB Hid Usage Tables v1.5, subsection 3.4.2.1 Added pidff_send_device_control which handles usage flag check which decides whether DEVICE_CONTROL should be handled as "One selection of a set" or "Any selection of a set". Reset was triggered once, on device initialization. Now, it's triggered every time when uploading an effect to an empty device (no currently stored effects), tracked by pidff->effect_count variable. Co-developed-by: Makarenko Oleg <oleg@makarenk.ooo> Signed-off-by: Makarenko Oleg <oleg@makarenk.ooo> Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com> Reviewed-by: Michał Kopeć <michal@nozomi.space> Reviewed-by: Paul Dino Jones <paul@spacefreak18.xyz> Tested-by: Paul Dino Jones <paul@spacefreak18.xyz> Tested-by: Cristóferson Bueno <cbueno81@gmail.com> Tested-by: Pablo Cisneros <patchkez@protonmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
1 parent abdbf87 commit cb3fd78

1 file changed

Lines changed: 89 additions & 49 deletions

File tree

drivers/hid/usbhid/hid-pidff.c

Lines changed: 89 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,10 @@ static const u8 pidff_pool[] = { 0x80, 0x83, 0xa9 };
109109
/* Special field key tables used to put special field keys into arrays */
110110

111111
#define PID_ENABLE_ACTUATORS 0
112-
#define PID_STOP_ALL_EFFECTS 1
113-
#define PID_RESET 2
114-
static const u8 pidff_device_control[] = { 0x97, 0x99, 0x9a };
112+
#define PID_DISABLE_ACTUATORS 1
113+
#define PID_STOP_ALL_EFFECTS 2
114+
#define PID_RESET 3
115+
static const u8 pidff_device_control[] = { 0x97, 0x98, 0x99, 0x9a };
115116

116117
#define PID_CONSTANT 0
117118
#define PID_RAMP 1
@@ -190,6 +191,7 @@ struct pidff_device {
190191
int pid_id[PID_EFFECTS_MAX];
191192

192193
u32 quirks;
194+
u8 effect_count;
193195
};
194196

195197
/*
@@ -490,9 +492,83 @@ static int pidff_needs_set_ramp(struct ff_effect *effect, struct ff_effect *old)
490492
effect->u.ramp.end_level != old->u.ramp.end_level;
491493
}
492494

495+
/*
496+
* Clear device control report
497+
*/
498+
static void pidff_send_device_control(struct pidff_device *pidff, int field)
499+
{
500+
int i, tmp;
501+
int field_index = pidff->control_id[field];
502+
503+
/* Detect if the field is a bitmask variable or an array */
504+
if (pidff->device_control->flags & HID_MAIN_ITEM_VARIABLE) {
505+
hid_dbg(pidff->hid, "DEVICE_CONTROL is a bitmask\n");
506+
/* Clear current bitmask */
507+
for(i = 0; i < sizeof(pidff_device_control); i++) {
508+
tmp = pidff->control_id[i];
509+
pidff->device_control->value[tmp] = 0;
510+
}
511+
pidff->device_control->value[field_index - 1] = 1;
512+
} else {
513+
hid_dbg(pidff->hid, "DEVICE_CONTROL is an array\n");
514+
pidff->device_control->value[0] = field_index;
515+
}
516+
517+
hid_hw_request(pidff->hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);
518+
hid_hw_wait(pidff->hid);
519+
}
520+
521+
/*
522+
* Modify actuators state
523+
*/
524+
static void pidff_modify_actuators_state(struct pidff_device *pidff, bool enable)
525+
{
526+
hid_dbg(pidff->hid, "%s actuators\n", enable ? "Enable" : "Disable");
527+
pidff_send_device_control(pidff,
528+
enable ? PID_ENABLE_ACTUATORS : PID_DISABLE_ACTUATORS);
529+
}
530+
531+
/*
532+
* Reset the device, stop all effects, enable actuators
533+
* Refetch pool report
534+
*/
535+
static void pidff_reset(struct pidff_device *pidff)
536+
{
537+
int i = 0;
538+
539+
/* We reset twice as sometimes hid_wait_io isn't waiting long enough */
540+
pidff_send_device_control(pidff, PID_RESET);
541+
pidff_send_device_control(pidff, PID_RESET);
542+
pidff->effect_count = 0;
543+
544+
pidff_send_device_control(pidff, PID_STOP_ALL_EFFECTS);
545+
pidff_modify_actuators_state(pidff, 1);
546+
547+
/* pool report is sometimes messed up, refetch it */
548+
hid_hw_request(pidff->hid, pidff->reports[PID_POOL], HID_REQ_GET_REPORT);
549+
hid_hw_wait(pidff->hid);
550+
551+
if (pidff->pool[PID_SIMULTANEOUS_MAX].value) {
552+
while (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] < 2) {
553+
if (i++ > 20) {
554+
hid_warn(pidff->hid,
555+
"device reports %d simultaneous effects\n",
556+
pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
557+
break;
558+
}
559+
hid_dbg(pidff->hid, "pid_pool requested again\n");
560+
hid_hw_request(pidff->hid, pidff->reports[PID_POOL],
561+
HID_REQ_GET_REPORT);
562+
hid_hw_wait(pidff->hid);
563+
}
564+
}
565+
}
566+
493567
/*
494568
* Send a request for effect upload to the device
495569
*
570+
* Reset and enable actuators if no effects were present on the device
571+
*
496572
* Returns 0 if device reported success, -ENOSPC if the device reported memory
497573
* is full. Upon unknown response the function will retry for 60 times, if
498574
* still unsuccessful -EIO is returned.
@@ -501,6 +577,9 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
501577
{
502578
int j;
503579

580+
if (!pidff->effect_count)
581+
pidff_reset(pidff);
582+
504583
pidff->create_new_effect_type->value[0] = efnum;
505584
hid_hw_request(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT],
506585
HID_REQ_SET_REPORT);
@@ -520,6 +599,8 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
520599
hid_dbg(pidff->hid, "device reported free memory: %d bytes\n",
521600
pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
522601
pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
602+
603+
pidff->effect_count++;
523604
return 0;
524605
}
525606
if (pidff->block_load_status->value[0] ==
@@ -568,12 +649,16 @@ static int pidff_playback(struct input_dev *dev, int effect_id, int value)
568649

569650
/*
570651
* Erase effect with PID id
652+
* Decrease the device effect counter
571653
*/
572654
static void pidff_erase_pid(struct pidff_device *pidff, int pid_id)
573655
{
574656
pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
575657
hid_hw_request(pidff->hid, pidff->reports[PID_BLOCK_FREE],
576658
HID_REQ_SET_REPORT);
659+
660+
if (pidff->effect_count > 0)
661+
pidff->effect_count--;
577662
}
578663

579664
/*
@@ -1211,50 +1296,6 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev)
12111296
return 0;
12121297
}
12131298

1214-
/*
1215-
* Reset the device
1216-
*/
1217-
static void pidff_reset(struct pidff_device *pidff)
1218-
{
1219-
struct hid_device *hid = pidff->hid;
1220-
int i = 0;
1221-
1222-
pidff->device_control->value[0] = pidff->control_id[PID_RESET];
1223-
/* We reset twice as sometimes hid_wait_io isn't waiting long enough */
1224-
hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);
1225-
hid_hw_wait(hid);
1226-
hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);
1227-
hid_hw_wait(hid);
1228-
1229-
pidff->device_control->value[0] = pidff->control_id[PID_STOP_ALL_EFFECTS];
1230-
hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);
1231-
hid_hw_wait(hid);
1232-
1233-
pidff->device_control->value[0] =
1234-
pidff->control_id[PID_ENABLE_ACTUATORS];
1235-
hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);
1236-
hid_hw_wait(hid);
1237-
1238-
/* pool report is sometimes messed up, refetch it */
1239-
hid_hw_request(hid, pidff->reports[PID_POOL], HID_REQ_GET_REPORT);
1240-
hid_hw_wait(hid);
1241-
1242-
if (pidff->pool[PID_SIMULTANEOUS_MAX].value) {
1243-
while (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] < 2) {
1244-
if (i++ > 20) {
1245-
hid_warn(pidff->hid,
1246-
"device reports %d simultaneous effects\n",
1247-
pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
1248-
break;
1249-
}
1250-
hid_dbg(pidff->hid, "pid_pool requested again\n");
1251-
hid_hw_request(hid, pidff->reports[PID_POOL],
1252-
HID_REQ_GET_REPORT);
1253-
hid_hw_wait(hid);
1254-
}
1255-
}
1256-
}
1257-
12581299
/*
12591300
* Test if autocenter modification is using the supported method
12601301
*/
@@ -1320,6 +1361,7 @@ int hid_pidff_init_with_quirks(struct hid_device *hid, __u32 initial_quirks)
13201361

13211362
pidff->hid = hid;
13221363
pidff->quirks = initial_quirks;
1364+
pidff->effect_count = 0;
13231365

13241366
hid_device_io_start(hid);
13251367

@@ -1336,8 +1378,6 @@ int hid_pidff_init_with_quirks(struct hid_device *hid, __u32 initial_quirks)
13361378
if (error)
13371379
goto fail;
13381380

1339-
pidff_reset(pidff);
1340-
13411381
if (test_bit(FF_GAIN, dev->ffbit)) {
13421382
pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff);
13431383
hid_hw_request(hid, pidff->reports[PID_DEVICE_GAIN],

0 commit comments

Comments
 (0)