Skip to content

Commit f8b6a74

Browse files
skomraJiri Kosina
authored andcommitted
HID: wacom: generic: Support multiple tools per report
Some Wacom devices contain contain Pen and Pad usages in the same report. Future devices of this type may utilize HID Descriptors. The generic code path of the Wacom driver previously assumed pen, touch, and pad reports were delivered in separate reports. This patch adds support for processing each collection of a report separately, in order to support reports with multiple tools. Signed-off-by: Aaron Armstrong Skomra <[email protected]> Reviewed-by: Ping Cheng <[email protected]> Reviewed-by: Jason Gerecke <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 87046b6 commit f8b6a74

File tree

1 file changed

+68
-26
lines changed

1 file changed

+68
-26
lines changed

drivers/hid/wacom_wac.c

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,15 +2072,15 @@ static void wacom_wac_pad_pre_report(struct hid_device *hdev,
20722072
}
20732073

20742074
static void wacom_wac_pad_report(struct hid_device *hdev,
2075-
struct hid_report *report)
2075+
struct hid_report *report, struct hid_field *field)
20762076
{
20772077
struct wacom *wacom = hid_get_drvdata(hdev);
20782078
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
20792079
struct input_dev *input = wacom_wac->pad_input;
20802080
bool active = wacom_wac->hid_data.inrange_state != 0;
20812081

20822082
/* report prox for expresskey events */
2083-
if ((wacom_equivalent_usage(report->field[0]->physical) == HID_DG_TABLETFUNCTIONKEY) &&
2083+
if ((wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) &&
20842084
wacom_wac->hid_data.pad_input_event_flag) {
20852085
input_event(input, EV_ABS, ABS_MISC, active ? PAD_DEVICE_ID : 0);
20862086
input_sync(input);
@@ -2627,11 +2627,13 @@ void wacom_wac_event(struct hid_device *hdev, struct hid_field *field,
26272627
wacom_wac_finger_event(hdev, field, usage, value);
26282628
}
26292629

2630-
static void wacom_report_events(struct hid_device *hdev, struct hid_report *report)
2630+
static void wacom_report_events(struct hid_device *hdev,
2631+
struct hid_report *report, int collection_index,
2632+
int field_index)
26312633
{
26322634
int r;
26332635

2634-
for (r = 0; r < report->maxfield; r++) {
2636+
for (r = field_index; r < report->maxfield; r++) {
26352637
struct hid_field *field;
26362638
unsigned count, n;
26372639

@@ -2641,30 +2643,23 @@ static void wacom_report_events(struct hid_device *hdev, struct hid_report *repo
26412643
if (!(HID_MAIN_ITEM_VARIABLE & field->flags))
26422644
continue;
26432645

2644-
for (n = 0; n < count; n++)
2645-
wacom_wac_event(hdev, field, &field->usage[n], field->value[n]);
2646+
for (n = 0 ; n < count; n++) {
2647+
if (field->usage[n].collection_index == collection_index)
2648+
wacom_wac_event(hdev, field, &field->usage[n],
2649+
field->value[n]);
2650+
else
2651+
return;
2652+
}
26462653
}
26472654
}
26482655

2649-
void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
2656+
int wacom_wac_collection(struct hid_device *hdev, struct hid_report *report,
2657+
int collection_index, struct hid_field *field,
2658+
int field_index)
26502659
{
26512660
struct wacom *wacom = hid_get_drvdata(hdev);
2652-
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
2653-
struct hid_field *field = report->field[0];
2654-
2655-
if (wacom_wac->features.type != HID_GENERIC)
2656-
return;
2657-
2658-
wacom_wac_battery_pre_report(hdev, report);
2659-
2660-
if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input)
2661-
wacom_wac_pad_pre_report(hdev, report);
2662-
else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
2663-
wacom_wac_pen_pre_report(hdev, report);
2664-
else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input)
2665-
wacom_wac_finger_pre_report(hdev, report);
26662661

2667-
wacom_report_events(hdev, report);
2662+
wacom_report_events(hdev, report, collection_index, field_index);
26682663

26692664
/*
26702665
* Non-input reports may be sent prior to the device being
@@ -2674,16 +2669,63 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
26742669
* processing functions.
26752670
*/
26762671
if (report->type != HID_INPUT_REPORT)
2677-
return;
2678-
2679-
wacom_wac_battery_report(hdev, report);
2672+
return -1;
26802673

26812674
if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input)
2682-
wacom_wac_pad_report(hdev, report);
2675+
wacom_wac_pad_report(hdev, report, field);
26832676
else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
26842677
wacom_wac_pen_report(hdev, report);
26852678
else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input)
26862679
wacom_wac_finger_report(hdev, report);
2680+
2681+
return 0;
2682+
}
2683+
2684+
void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
2685+
{
2686+
struct wacom *wacom = hid_get_drvdata(hdev);
2687+
struct wacom_wac *wacom_wac = &wacom->wacom_wac;
2688+
struct hid_field *field;
2689+
bool pad_in_hid_field = false, pen_in_hid_field = false,
2690+
finger_in_hid_field = false;
2691+
int r;
2692+
int prev_collection = -1;
2693+
2694+
if (wacom_wac->features.type != HID_GENERIC)
2695+
return;
2696+
2697+
for (r = 0; r < report->maxfield; r++) {
2698+
field = report->field[r];
2699+
2700+
if (WACOM_PAD_FIELD(field))
2701+
pad_in_hid_field = true;
2702+
if (WACOM_PEN_FIELD(field))
2703+
pen_in_hid_field = true;
2704+
if (WACOM_FINGER_FIELD(field))
2705+
finger_in_hid_field = true;
2706+
}
2707+
2708+
wacom_wac_battery_pre_report(hdev, report);
2709+
2710+
if (pad_in_hid_field && wacom->wacom_wac.pad_input)
2711+
wacom_wac_pad_pre_report(hdev, report);
2712+
if (pen_in_hid_field && wacom->wacom_wac.pen_input)
2713+
wacom_wac_pen_pre_report(hdev, report);
2714+
if (finger_in_hid_field && wacom->wacom_wac.touch_input)
2715+
wacom_wac_finger_pre_report(hdev, report);
2716+
2717+
for (r = 0; r < report->maxfield; r++) {
2718+
field = report->field[r];
2719+
2720+
if (field->usage[0].collection_index != prev_collection) {
2721+
if (wacom_wac_collection(hdev, report,
2722+
field->usage[0].collection_index, field, r) < 0)
2723+
return;
2724+
prev_collection = field->usage[0].collection_index;
2725+
}
2726+
}
2727+
2728+
wacom_wac_battery_report(hdev, report);
26872729
}
26882730

26892731
static int wacom_bpt_touch(struct wacom_wac *wacom)

0 commit comments

Comments
 (0)