* [PATCH 4/8] HID: input: use the Resolution Multiplier for high-resolution scrolling
From: Peter Hutterer @ 2018-11-22 6:34 UTC (permalink / raw)
To: linux-input
Cc: Dmitry Torokhov, Jiri Kosina, Harry Cutts, torvalds,
Nestor Lopez Casado, linux-kernel, Benjamin Tissoires
In-Reply-To: <20181122063409.15816-1-peter.hutterer@who-t.net>
Windows uses a magic number of 120 for a wheel click. High-resolution
scroll wheels are supposed to use a fraction of 120 to signal smaller
scroll steps. This is implemented by the Resolution Multiplier in the
device itself.
If the multiplier is present in the report descriptor, set it to the
logical max and then use the resolution multiplier to calculate the
high-resolution events. This is the recommendation by Microsoft, see
http://msdn.microsoft.com/en-us/windows/hardware/gg487477.aspx
Note that all mice encountered so far have a logical min/max of 0/1, so
it's a binary "yes or no" to high-res scrolling anyway.
To make userspace simpler, always enable the REL_WHEEL_HI_RES bit. Where
the device doesn't support high-resolution scrolling, the value for the
high-res data will simply be a multiple of 120 every time. For userspace,
if REL_WHEEL_HI_RES is available that is the one to be used.
Potential side-effect: a device with a Resolution Multiplier applying to
other Input items will have those items set to the logical max as well.
This cannot easily be worked around but it is doubtful such devices exist.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
drivers/hid/hid-input.c | 137 ++++++++++++++++++++++++++++++++++++++--
include/linux/hid.h | 3 +
2 files changed, 136 insertions(+), 4 deletions(-)
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index ad823a01bd65..cf0f2ae2dbf5 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -562,6 +562,17 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
}
#endif /* CONFIG_HID_BATTERY_STRENGTH */
+static void hidinput_set_wheel_factor(struct hid_usage *usage)
+{
+ /*
+ * Windows reports one wheels click as value 120. Where a high-res
+ * scroll wheel is present, a fraction of 120 is reported instead.
+ * Our REL_WHEEL_HI_RES axis does the same because all HW must
+ * adhere to the 120 expectation.
+ */
+ usage->wheel_factor = 120/usage->resolution_multiplier;
+}
+
static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
struct hid_usage *usage)
{
@@ -709,7 +720,16 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
map_abs_clear(usage->hid & 0xf);
break;
- case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL:
+ case HID_GD_WHEEL:
+ if (field->flags & HID_MAIN_ITEM_RELATIVE) {
+ hidinput_set_wheel_factor(usage);
+ set_bit(REL_WHEEL, input->relbit);
+ map_rel(REL_WHEEL_HI_RES);
+ } else {
+ map_abs(usage->hid & 0xf);
+ }
+ break;
+ case HID_GD_SLIDER: case HID_GD_DIAL:
if (field->flags & HID_MAIN_ITEM_RELATIVE)
map_rel(usage->hid & 0xf);
else
@@ -1009,7 +1029,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x22f: map_key_clear(KEY_ZOOMRESET); break;
case 0x233: map_key_clear(KEY_SCROLLUP); break;
case 0x234: map_key_clear(KEY_SCROLLDOWN); break;
- case 0x238: map_rel(REL_HWHEEL); break;
+ case 0x238: /* AC Pan */
+ hidinput_set_wheel_factor(usage);
+ set_bit(REL_HWHEEL, input->relbit);
+ map_rel(REL_HWHEEL_HI_RES);
+ break;
case 0x23d: map_key_clear(KEY_EDIT); break;
case 0x25f: map_key_clear(KEY_CANCEL); break;
case 0x269: map_key_clear(KEY_INSERT); break;
@@ -1026,7 +1050,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case 0x2ca: map_key_clear(KEY_KBDINPUTASSIST_NEXTGROUP); break;
case 0x2cb: map_key_clear(KEY_KBDINPUTASSIST_ACCEPT); break;
case 0x2cc: map_key_clear(KEY_KBDINPUTASSIST_CANCEL); break;
-
default: map_key_clear(KEY_UNKNOWN);
}
break;
@@ -1197,6 +1220,39 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
}
+static void hidinput_handle_scroll(struct hid_device *hid,
+ struct hid_field *field,
+ struct hid_usage *usage,
+ struct input_dev *input,
+ __s32 value)
+{
+ int code;
+ struct hid_input *hidinput;
+ int hi_res, lo_res;
+
+ if (value == 0)
+ return;
+
+ hidinput = field->hidinput;
+ if (!hidinput)
+ return;
+
+ if (usage->code == REL_WHEEL_HI_RES)
+ code = REL_WHEEL;
+ else
+ code = REL_HWHEEL;
+
+ hi_res = usage->wheel_factor * value;
+
+ usage->wheel_accumulated += hi_res;
+ lo_res = usage->wheel_accumulated/120;
+ if (lo_res)
+ usage->wheel_accumulated -= lo_res * 120;
+
+ input_event(input, EV_REL, code, lo_res);
+ input_event(input, EV_REL, usage->code, hi_res);
+}
+
void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
{
struct input_dev *input;
@@ -1259,6 +1315,12 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */
return;
+ if ((usage->type == EV_REL) && (usage->code == REL_WHEEL_HI_RES ||
+ usage->code == REL_HWHEEL_HI_RES)) {
+ hidinput_handle_scroll(hid, field, usage, input, value);
+ return;
+ }
+
if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) &&
(usage->code == ABS_VOLUME)) {
int count = abs(value);
@@ -1486,6 +1548,72 @@ static void hidinput_close(struct input_dev *dev)
hid_hw_close(hid);
}
+static void hidinput_change_resolution_multipliers(struct hid_device *hid)
+{
+ struct hid_report_enum *rep_enum;
+ struct hid_report *rep;
+ struct hid_usage *usage;
+ int i, j;
+
+ rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
+ list_for_each_entry(rep, &rep_enum->report_list, list) {
+ bool update_needed = false;
+
+ if (rep->maxfield == 0)
+ continue;
+
+ /*
+ * If we have more than one feature within this report we
+ * need to fill in the bits from the others before we can
+ * overwrite the ones for the Resolution Multiplier.
+ */
+ if (rep->maxfield > 1) {
+ hid_hw_request(hid, rep, HID_REQ_GET_REPORT);
+ hid_hw_wait(hid);
+ }
+
+ for (i = 0; i < rep->maxfield; i++) {
+ __s32 logical_max = rep->field[i]->logical_maximum;
+
+ /* There is no good reason for a Resolution
+ * Multiplier to have a count other than 1.
+ * Ignore that case.
+ */
+ if (rep->field[i]->report_count != 1)
+ continue;
+
+ for (j = 0; j < rep->field[i]->maxusage; j++) {
+ usage = &rep->field[i]->usage[j];
+
+ if (usage->hid != HID_GD_RESOLUTION_MULTIPLIER)
+ continue;
+
+ *rep->field[i]->value = logical_max;
+ update_needed = true;
+ }
+ }
+ if (update_needed)
+ hid_hw_request(hid, rep, HID_REQ_SET_REPORT);
+ }
+
+ /* refresh our structs */
+ hid_setup_resolution_multiplier(hid);
+
+ /* now refresh the wheel factor */
+ rep_enum = &hid->report_enum[HID_INPUT_REPORT];
+ list_for_each_entry(rep, &rep_enum->report_list, list) {
+ for (i = 0; i < rep->maxfield; i++) {
+ for (j = 0; j < rep->field[i]->maxusage; j++) {
+ usage = &rep->field[i]->usage[j];
+
+ if (usage->hid == HID_GD_WHEEL ||
+ usage->hid == HID_CP_AC_PAN)
+ hidinput_set_wheel_factor(usage);
+ }
+ }
+ }
+}
+
static void report_features(struct hid_device *hid)
{
struct hid_driver *drv = hid->driver;
@@ -1779,6 +1907,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
}
}
+ hidinput_change_resolution_multipliers(hid);
+
list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
if (drv->input_configured &&
drv->input_configured(hid, hidinput))
@@ -1837,4 +1967,3 @@ void hidinput_disconnect(struct hid_device *hid)
cancel_work_sync(&hid->led_work);
}
EXPORT_SYMBOL_GPL(hidinput_disconnect);
-
diff --git a/include/linux/hid.h b/include/linux/hid.h
index fd8d860365a4..93db548f8761 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -233,6 +233,7 @@ struct hid_item {
#define HID_DC_BATTERYSTRENGTH 0x00060020
#define HID_CP_CONSUMER_CONTROL 0x000c0001
+#define HID_CP_AC_PAN 0x000c0238
#define HID_DG_DIGITIZER 0x000d0001
#define HID_DG_PEN 0x000d0002
@@ -441,11 +442,13 @@ struct hid_usage {
__s8 resolution_multiplier;/* Effective Resolution Multiplier
(HUT v1.12, 4.3.1), default: 1 */
/* hidinput data */
+ __s8 wheel_factor; /* 120/resolution_multiplier */
__u16 code; /* input driver code */
__u8 type; /* input driver type */
__s8 hat_min; /* hat switch fun */
__s8 hat_max; /* ditto */
__s8 hat_dir; /* ditto */
+ __s16 wheel_accumulated; /* hi-res wheel */
};
struct hid_input;
--
2.19.1
^ permalink raw reply related
* [PATCH 3/8] HID: core: process the Resolution Multiplier
From: Peter Hutterer @ 2018-11-22 6:34 UTC (permalink / raw)
To: linux-input
Cc: Dmitry Torokhov, Jiri Kosina, Harry Cutts, torvalds,
Nestor Lopez Casado, linux-kernel, Benjamin Tissoires
In-Reply-To: <20181122063409.15816-1-peter.hutterer@who-t.net>
The Resolution Multiplier is a feature report that modifies the value of
Usages within the same Logical Collection. Where set, the effective
multiplier (calculated based on the physical dimensions of the multiplier
field) affects the event value. That's done in hardware, so the values we
receive are pre-multiplied.
This was introduced for high-resolution scrolling in Windows Vista and is
commonly used on Microsoft mice.
The recommendation for the resolution multiplier is to be 1 by default. We
put some extra limits here to cap at 255. The only known usage for this is
for scroll wheels where the multiplier has to be a fraction of 120 to work
with Windows.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
drivers/hid/hid-core.c | 170 +++++++++++++++++++++++++++++++++++++++++
include/linux/hid.h | 5 ++
2 files changed, 175 insertions(+)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 43d488a45120..f41d5fe51abe 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -294,6 +294,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
field->usage[i].collection_index =
parser->local.collection_index[j];
field->usage[i].usage_index = i;
+ field->usage[i].resolution_multiplier = 1;
}
field->maxusage = usages;
@@ -947,6 +948,167 @@ struct hid_report *hid_validate_values(struct hid_device *hid,
}
EXPORT_SYMBOL_GPL(hid_validate_values);
+static int hid_calculate_multiplier(struct hid_device *hid,
+ struct hid_field *multiplier)
+{
+ int m;
+ __s32 v = *multiplier->value;
+ __s32 lmin = multiplier->logical_minimum;
+ __s32 lmax = multiplier->logical_maximum;
+ __s32 pmin = multiplier->physical_minimum;
+ __s32 pmax = multiplier->physical_maximum;
+
+ /*
+ * "Because OS implementations will generally divide the control's
+ * reported count by the Effective Resolution Multiplier, designers
+ * should take care not to establish a potential Effective
+ * Resolution Multiplier of zero."
+ * HID Usage Table, v1.12, Section 4.3.1, p31
+ */
+ if (lmax - lmin == 0)
+ return 1;
+ /*
+ * Handling the unit exponent is left as an exercise to whoever
+ * finds a device where that exponent is not 0.
+ */
+ m = ((v - lmin)/(lmax - lmin) * (pmax - pmin) + pmin);
+ if (unlikely(multiplier->unit_exponent != 0)) {
+ hid_warn(hid,
+ "unsupported Resolution Multiplier unit exponent %d\n",
+ multiplier->unit_exponent);
+ }
+
+ /* There are no devices with an effective multiplier > 255 */
+ if (unlikely(m == 0 || m > 255 || m < -255)) {
+ hid_warn(hid, "unsupported Resolution Multiplier %d\n", m);
+ m = 1;
+ }
+
+ return m;
+}
+
+static void hid_apply_multiplier_to_field(struct hid_device *hid,
+ struct hid_field *field,
+ struct hid_collection *multiplier_collection,
+ int effective_multiplier)
+{
+ struct hid_collection *collection;
+ struct hid_usage *usage;
+ int i;
+
+ /*
+ * If multiplier_collection is NULL, the multiplier applies
+ * to all fields in the report.
+ * Otherwise, it is the Logical Collection the multiplier applies to
+ * but our field may be in a subcollection of that collection.
+ */
+ for (i = 0; i < field->maxusage; i++) {
+ usage = &field->usage[i];
+
+ collection = &hid->collection[usage->collection_index];
+ while (collection && collection != multiplier_collection)
+ collection = collection->parent;
+
+ if (collection || multiplier_collection == NULL)
+ usage->resolution_multiplier = effective_multiplier;
+
+ }
+}
+
+static void hid_apply_multiplier(struct hid_device *hid,
+ struct hid_field *multiplier)
+{
+ struct hid_report_enum *rep_enum;
+ struct hid_report *rep;
+ struct hid_field *field;
+ struct hid_collection *multiplier_collection;
+ int effective_multiplier;
+ int i;
+
+ /*
+ * "The Resolution Multiplier control must be contained in the same
+ * Logical Collection as the control(s) to which it is to be applied.
+ * If no Resolution Multiplier is defined, then the Resolution
+ * Multiplier defaults to 1. If more than one control exists in a
+ * Logical Collection, the Resolution Multiplier is associated with
+ * all controls in the collection. If no Logical Collection is
+ * defined, the Resolution Multiplier is associated with all
+ * controls in the report."
+ * HID Usage Table, v1.12, Section 4.3.1, p30
+ *
+ * Thus, search from the current collection upwards until we find a
+ * logical collection. Then search all fields for that same parent
+ * collection. Those are the fields the multiplier applies to.
+ *
+ * If we have more than one multiplier, it will overwrite the
+ * applicable fields later.
+ */
+ multiplier_collection = &hid->collection[multiplier->usage->collection_index];
+ while (multiplier_collection &&
+ multiplier_collection->type != HID_COLLECTION_LOGICAL)
+ multiplier_collection = multiplier_collection->parent;
+
+ effective_multiplier = hid_calculate_multiplier(hid, multiplier);
+
+ rep_enum = &hid->report_enum[HID_INPUT_REPORT];
+ list_for_each_entry(rep, &rep_enum->report_list, list) {
+ for (i = 0; i < rep->maxfield; i++) {
+ field = rep->field[i];
+ hid_apply_multiplier_to_field(hid, field,
+ multiplier_collection,
+ effective_multiplier);
+ }
+ }
+}
+
+/*
+ * hid_setup_resolution_multiplier - set up all resolution multipliers
+ *
+ * @device: hid device
+ *
+ * Search for all Resolution Multiplier Feature Reports and apply their
+ * value to all matching Input items. This only updates the internal struct
+ * fields.
+ *
+ * The Resolution Multiplier is applied by the hardware. If the multiplier
+ * is anything other than 1, the hardware will send pre-multiplied events
+ * so that the same physical interaction generates an accumulated
+ * accumulated_value = value * * multiplier
+ * This may be achieved by sending
+ * - "value * multiplier" for each event, or
+ * - "value" but "multiplier" times as frequently, or
+ * - a combination of the above
+ * The only guarantee is that the same physical interaction always generates
+ * an accumulated 'value * multiplier'.
+ *
+ * This function must be called before any event processing and after
+ * any SetRequest to the Resolution Multiplier.
+ */
+void hid_setup_resolution_multiplier(struct hid_device *hid)
+{
+ struct hid_report_enum *rep_enum;
+ struct hid_report *rep;
+ struct hid_usage *usage;
+ int i, j;
+
+ rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
+ list_for_each_entry(rep, &rep_enum->report_list, list) {
+ for (i = 0; i < rep->maxfield; i++) {
+ /* Ignore if report count is out of bounds. */
+ if (rep->field[i]->report_count < 1)
+ continue;
+
+ for (j = 0; j < rep->field[i]->maxusage; j++) {
+ usage = &rep->field[i]->usage[j];
+ if (usage->hid == HID_GD_RESOLUTION_MULTIPLIER)
+ hid_apply_multiplier(hid,
+ rep->field[i]);
+ }
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(hid_setup_resolution_multiplier);
+
/**
* hid_open_report - open a driver-specific device report
*
@@ -1043,9 +1205,17 @@ int hid_open_report(struct hid_device *device)
hid_err(device, "unbalanced delimiter at end of report description\n");
goto err;
}
+
+ /*
+ * fetch initial values in case the device's
+ * default multiplier isn't the recommended 1
+ */
+ hid_setup_resolution_multiplier(device);
+
kfree(parser->collection_stack);
vfree(parser);
device->status |= HID_STAT_PARSED;
+
return 0;
}
}
diff --git a/include/linux/hid.h b/include/linux/hid.h
index fdfda898656c..fd8d860365a4 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -219,6 +219,7 @@ struct hid_item {
#define HID_GD_VBRZ 0x00010045
#define HID_GD_VNO 0x00010046
#define HID_GD_FEATURE 0x00010047
+#define HID_GD_RESOLUTION_MULTIPLIER 0x00010048
#define HID_GD_SYSTEM_CONTROL 0x00010080
#define HID_GD_UP 0x00010090
#define HID_GD_DOWN 0x00010091
@@ -437,6 +438,8 @@ struct hid_usage {
unsigned hid; /* hid usage code */
unsigned collection_index; /* index into collection array */
unsigned usage_index; /* index into usage array */
+ __s8 resolution_multiplier;/* Effective Resolution Multiplier
+ (HUT v1.12, 4.3.1), default: 1 */
/* hidinput data */
__u16 code; /* input driver code */
__u8 type; /* input driver type */
@@ -894,6 +897,8 @@ struct hid_report *hid_validate_values(struct hid_device *hid,
unsigned int type, unsigned int id,
unsigned int field_index,
unsigned int report_counts);
+
+void hid_setup_resolution_multiplier(struct hid_device *hid);
int hid_open_report(struct hid_device *device);
int hid_check_keys_pressed(struct hid_device *hid);
int hid_connect(struct hid_device *hid, unsigned int connect_mask);
--
2.19.1
^ permalink raw reply related
* [PATCH 2/8] HID: core: store the collections as a basic tree
From: Peter Hutterer @ 2018-11-22 6:34 UTC (permalink / raw)
To: linux-input
Cc: Dmitry Torokhov, Jiri Kosina, Harry Cutts, torvalds,
Nestor Lopez Casado, linux-kernel, Benjamin Tissoires
In-Reply-To: <20181122063409.15816-1-peter.hutterer@who-t.net>
For each collection parsed, store a pointer to the parent collection
(if any). This makes it a lot easier to look up which collection(s)
any given item is part of
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
drivers/hid/hid-core.c | 4 ++++
include/linux/hid.h | 2 ++
2 files changed, 6 insertions(+)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 5bec9244c45b..43d488a45120 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -172,6 +172,8 @@ static int open_collection(struct hid_parser *parser, unsigned type)
collection->type = type;
collection->usage = usage;
collection->level = parser->collection_stack_ptr - 1;
+ collection->parent = parser->active_collection;
+ parser->active_collection = collection;
if (type == HID_COLLECTION_APPLICATION)
parser->device->maxapplication++;
@@ -190,6 +192,8 @@ static int close_collection(struct hid_parser *parser)
return -EINVAL;
}
parser->collection_stack_ptr--;
+ if (parser->active_collection)
+ parser->active_collection = parser->active_collection->parent;
return 0;
}
diff --git a/include/linux/hid.h b/include/linux/hid.h
index a355d61940f2..fdfda898656c 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -427,6 +427,7 @@ struct hid_local {
*/
struct hid_collection {
+ struct hid_collection *parent;
unsigned type;
unsigned usage;
unsigned level;
@@ -650,6 +651,7 @@ struct hid_parser {
unsigned int *collection_stack;
unsigned int collection_stack_ptr;
unsigned int collection_stack_size;
+ struct hid_collection *active_collection;
struct hid_device *device;
unsigned int scan_flags;
};
--
2.19.1
^ permalink raw reply related
* [PATCH 1/8] Input: add `REL_WHEEL_HI_RES` and `REL_HWHEEL_HI_RES`
From: Peter Hutterer @ 2018-11-22 6:34 UTC (permalink / raw)
To: linux-input
Cc: Dmitry Torokhov, Jiri Kosina, Harry Cutts, torvalds,
Nestor Lopez Casado, linux-kernel, Benjamin Tissoires
In-Reply-To: <20181122063409.15816-1-peter.hutterer@who-t.net>
This event code represents scroll reports from high-resolution wheels and
is modelled after the approach Windows uses. The value 120 is one detent
(wheel click) of movement. Mice with higher-resolution scrolling can send
fractions of 120 to be accumulate in userspace. Userspace can either wait
for 120 to accumulate or scroll by fractions of one logical scroll movement
as the events come in.
For more information see
https://docs.microsoft.com/en-us/previous-versions/windows/hardware/design/dn613912(v=vs.85)
These new axes obsolete REL_WHEEL and REL_HWHEEL. The legacy axes are
emulated but the most accurate (and most granular) data is available
through the new axes.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
Documentation/input/event-codes.rst | 21 ++++++++++++++++++++-
include/uapi/linux/input-event-codes.h | 2 ++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/Documentation/input/event-codes.rst b/Documentation/input/event-codes.rst
index a8c0873beb95..b24b5343f5eb 100644
--- a/Documentation/input/event-codes.rst
+++ b/Documentation/input/event-codes.rst
@@ -190,7 +190,26 @@ A few EV_REL codes have special meanings:
* REL_WHEEL, REL_HWHEEL:
- These codes are used for vertical and horizontal scroll wheels,
- respectively.
+ respectively. The value is the number of detents moved on the wheel, the
+ physical size of which varies by device. For high-resolution wheels
+ this may be an approximation based on the high-resolution scroll events,
+ see REL_WHEEL_HI_RES. These event codes are legacy codes and
+ REL_WHEEL_HI_RES and REL_HWHEEL_HI_RES should be preferred where
+ available.
+
+* REL_WHEEL_HI_RES, REL_HWHEEL_HI_RES:
+
+ - High-resolution scroll wheel data. The accumulated value 120 represents
+ movement by one detent. For devices that do not provide high-resolution
+ scrolling, the value is always a multiple of 120. For devices with
+ high-resolution scrolling, the value may be a fraction of 120.
+
+ If a vertical scroll wheel supports high-resolution scrolling, this code
+ will be emitted in addition to REL_WHEEL or REL_HWHEEL. The REL_WHEEL
+ and REL_HWHEEL may be an approximation based on the high-resolution
+ scroll events. There is no guarantee that the high-resolution data
+ is a multiple of 120 at the time of an emulated REL_WHEEL or REL_HWHEEL
+ event.
EV_ABS
------
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h
index ae366b87426a..7f14d4a66c28 100644
--- a/include/uapi/linux/input-event-codes.h
+++ b/include/uapi/linux/input-event-codes.h
@@ -716,6 +716,8 @@
* the situation described above.
*/
#define REL_RESERVED 0x0a
+#define REL_WHEEL_HI_RES 0x0b
+#define REL_HWHEEL_HI_RES 0x0c
#define REL_MAX 0x0f
#define REL_CNT (REL_MAX+1)
--
2.19.1
^ permalink raw reply related
* [PATCH 0/8] HID: MS and Logitech high-resolution scroll wheel support
From: Peter Hutterer @ 2018-11-22 6:34 UTC (permalink / raw)
To: linux-input
Cc: Dmitry Torokhov, Jiri Kosina, Harry Cutts, torvalds,
Nestor Lopez Casado, linux-kernel, Benjamin Tissoires
This series enables high-resolution scrolling on some or many Microsoft mice
of the last decade and Logitech mice with the required feature support.
High resolution scrolling is exposed to userspace as REL_WHEEL_HI_RES and
REL_HWHEEL_HI_RES. An accumulated value of 120 signals one wheel click, mice
with higher granularity can send multiple values that are fractions of 120.
REL_WHEEL and REL_HWHEEL are emulated for backwards compatibility.
The 120 magic number comes from Windows and affects how hardware vendors
build their shiny (and the use of a multiplier in the hw that is a whole
fraction of 120).
This series adds implementations for generic HID and for Logitech's HID++.
Windows Vista added the Resolution Multiplier HID feature which gives
us a multiplier that is applied (in hardware) to the wheel data. For the
same physical motion and an example multiplier of 8, the hardware may:
- send 8 events of value 1, or
- send 1 event of value 8, or
- send 8/n events of value 1 * n
The multiplier is a HID Feature and should default to an effective 1 in the
hardware. Windows Vista and newer set this to the logical maximum, we do the
same now. It's an approved HID Feature but so far, this feature has only
been found on some Microsoft mice.
Logitech mice do not seem to use it and have their own HID++ protocol to
apply that multiplier. Harry's patchset had previously been merged, the
exact implementation was incompatible with the Microsoft bits though so it
was reverted. Harry's patches in this series are adjusted accordingly but
are by and large the same.
Notable: The Logitech REL_WHEEL emulation cannot just hook into the HID
bits. The firmware drops some events so the point when we get the REL_WHEEL
event moves around. This is worked around by directional resets and a
timeout-based reset.
Devices tested:
- Microsoft Comfort Optical Mouse 3000
- Microsoft Sculpt Ergonomic Mouse
- Microsoft Surface mouse
- Logitech MX Anywhere 2S
The following devices were tested for the HID feature and didn't have it:
- Logitech G500s, G303
- Roccat Kone XTD
- all the cheap Lenovo, HP, Dell, Logitech USB mice that come with a
workstation that I could find in the local office
- Etekcity something something
- Razer Imperator
- Microsoft Classic IntelliMouse
- Microsoft Surface Mobile Mouse
Cheers,
Peter
Harry Cutts (3):
HID: logitech: Use LDJ_DEVICE macro for existing Logitech mice
HID: logitech: Add function to enable HID++ 1.0 "scrolling acceleration"
HID: logitech: Enable high-resolution scrolling on Logitech mice
Peter Hutterer (5):
Input: add `REL_WHEEL_HI_RES` and `REL_HWHEEL_HI_RES`
HID: core: store the collections as a basic tree
HID: core: process the Resolution Multiplier
HID: input: use the Resolution Multiplier for high-resolution scrolling
HID: logitech-hidpp: fix typo, hiddpp to hidpp
Documentation/input/event-codes.rst | 21 +++-
drivers/hid/hid-core.c | 174 ++++++++++++++++++++++++++++++++
drivers/hid/hid-input.c | 137 ++++++++++++++++++++++++-
drivers/hid/hid-logitech-hidpp.c | 384 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
include/linux/hid.h | 10 ++
include/uapi/linux/input-event-codes.h | 2 +
6 files changed, 690 insertions(+), 38 deletions(-)
^ permalink raw reply
* Elantech SMBus support regression
From: Kai Heng Feng @ 2018-11-22 4:21 UTC (permalink / raw)
To: Benjamin Tissoires; +Cc: open list:HID CORE LAYER, Linux Kernel Mailing List
Hi Benjamin,
It appears the Elantech SMBus support breaks some users’ touchpad.
Please have a look at [1] [2], thanks!
[1] https://bugs.launchpad.net/bugs/1803600
[2] https://bugs.archlinux.org/task/59714
Kai-Heng
^ permalink raw reply
* [PATCH] HID: intel-ish-hid: fixes incorrect error handling
From: Pan Bian @ 2018-11-22 0:52 UTC (permalink / raw)
To: Srinivas Pandruvada, Jiri Kosina, Benjamin Tissoires
Cc: linux-input, linux-kernel
The memory chunk allocated by hid_allocate_device() should be released
by hid_destroy_device(), not kfree().
Fixes: 0b28cb4bcb1("HID: intel-ish-hid: ISH HID client driver")
Signed-off-by: Pan Bian <bianpan2016@163.com>
---
drivers/hid/intel-ish-hid/ishtp-hid.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hid/intel-ish-hid/ishtp-hid.c b/drivers/hid/intel-ish-hid/ishtp-hid.c
index cd23903..e918d78 100644
--- a/drivers/hid/intel-ish-hid/ishtp-hid.c
+++ b/drivers/hid/intel-ish-hid/ishtp-hid.c
@@ -222,7 +222,7 @@ int ishtp_hid_probe(unsigned int cur_hid_dev,
err_hid_device:
kfree(hid_data);
err_hid_data:
- kfree(hid);
+ hid_destroy_device(hid);
return rv;
}
--
2.7.4
^ permalink raw reply related
* [PATCH] Input: synaptics - Add PNP ID for ThinkPad P50 to SMBus
From: Lyude Paul @ 2018-11-21 20:16 UTC (permalink / raw)
To: linux-input
Cc: Dmitry Torokhov, Benjamin Tissoires, KT Liao, Peter Hutterer,
Edvard Holst, Arkadiusz Hiler, linux-kernel
Noticed the other day the trackpoint felt different on my P50, then
realized it was because rmi4 wasn't loading for this machine
automatically. Suspend/resume, hibernate, and everything else seem to
work perfectly fine on here.
Signed-off-by: Lyude Paul <lyude@redhat.com>
---
drivers/input/mouse/synaptics.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 5e85f3cca867..c42813d50591 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -170,6 +170,7 @@ static const char * const smbus_pnp_ids[] = {
"LEN0048", /* X1 Carbon 3 */
"LEN0046", /* X250 */
"LEN004a", /* W541 */
+ "LEN005b", /* P50 */
"LEN0071", /* T480 */
"LEN0072", /* X1 Carbon Gen 5 (2017) - Elan/ALPS trackpoint */
"LEN0073", /* X1 Carbon G5 (Elantech) */
--
2.19.1
^ permalink raw reply related
* Re: [PATCH 0/7] HID: revert the Logitech High Resolution wheel support
From: Jiri Kosina @ 2018-11-21 18:46 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Dmitry Torokhov, Harry Cutts, Peter Hutterer, torvalds,
Nestor Lopez Casado, linux-input, linux-kernel
In-Reply-To: <20181121152712.6770-1-benjamin.tissoires@redhat.com>
On Wed, 21 Nov 2018, Benjamin Tissoires wrote:
> It turns out that the implementation of the high resolution support of
> Logitech wheels is rather incompatible with the mice from Microsoft.
>
> We had a lengthy discussion off-list and the summary is quoted in 7/7.
>
> The TL;DR, we need to revert the current series before it gets out in
> a released kernel and work on a better approach for 4.21.
>
> This patch series has informally been acked by Dmitry, Harry, Jiri, Nestor
> and Peter, but I wouldn't mind a public ack before I push this to
> the for-linus branch.
As discussed previously
Acked-by: Jiri Kosina <jkosina@suse.cz>
Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH 0/7] HID: revert the Logitech High Resolution wheel support
From: Dmitry Torokhov @ 2018-11-21 18:44 UTC (permalink / raw)
To: Harry Cutts
Cc: benjamin.tissoires, jikos, Peter Hutterer, torvalds,
Nestor Lopez Casado, linux-input, linux-kernel
In-Reply-To: <CA+jURctziob_scb36s-JxvD-FFrH1xn4Npd_i56g3DxxVEpZ4A@mail.gmail.com>
On Wed, Nov 21, 2018 at 10:37:13AM -0800, Harry Cutts wrote:
> On Wed, 21 Nov 2018 at 07:27, Benjamin Tissoires
> <benjamin.tissoires@redhat.com> wrote:
> > The TL;DR, we need to revert the current series before it gets out in
> > a released kernel and work on a better approach for 4.21.
> >
> > This patch series has informally been acked by Dmitry, Harry, Jiri, Nestor
> > and Peter, but I wouldn't mind a public ack before I push this to
> > the for-linus branch.
>
> Thanks Benjamin!
>
> For the series:
> Acked-by: Harry Cutts <hcutts@chromium.org>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Thanks!
--
Dmitry
^ permalink raw reply
* Re: [PATCH 0/7] HID: revert the Logitech High Resolution wheel support
From: Harry Cutts @ 2018-11-21 18:37 UTC (permalink / raw)
To: benjamin.tissoires
Cc: Dmitry Torokhov, jikos, Peter Hutterer, torvalds,
Nestor Lopez Casado, linux-input, linux-kernel
In-Reply-To: <20181121152712.6770-1-benjamin.tissoires@redhat.com>
On Wed, 21 Nov 2018 at 07:27, Benjamin Tissoires
<benjamin.tissoires@redhat.com> wrote:
> The TL;DR, we need to revert the current series before it gets out in
> a released kernel and work on a better approach for 4.21.
>
> This patch series has informally been acked by Dmitry, Harry, Jiri, Nestor
> and Peter, but I wouldn't mind a public ack before I push this to
> the for-linus branch.
Thanks Benjamin!
For the series:
Acked-by: Harry Cutts <hcutts@chromium.org>
Harry Cutts
Chrome OS Touch/Input team
^ permalink raw reply
* [PATCH 7/7] Revert "Input: Add the `REL_WHEEL_HI_RES` event code"
From: Benjamin Tissoires @ 2018-11-21 15:27 UTC (permalink / raw)
To: Dmitry Torokhov, Jiri Kosina, Harry Cutts, Peter Hutterer,
torvalds
Cc: Nestor Lopez Casado, linux-input, linux-kernel,
Benjamin Tissoires
In-Reply-To: <20181121152712.6770-1-benjamin.tissoires@redhat.com>
This reverts commit aaf9978c3c0291ef3beaa97610bc9c3084656a85.
Quoting Peter:
There is a HID feature report called "Resolution Multiplier"
Described in the "Enhanced Wheel Support in Windows" doc and
the "USB HID Usage Tables" page 30.
http://download.microsoft.com/download/b/d/1/bd1f7ef4-7d72-419e-bc5c-9f79ad7bb66e/wheel.docx
https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf
This was new for Windows Vista, so we're only a decade behind here. I only
accidentally found this a few days ago while debugging a stuck button on a
Microsoft mouse.
The docs above describe it like this: a wheel control by default sends
value 1 per notch. If the resolution multiplier is active, the wheel is
expected to send a value of $multiplier per notch (e.g. MS Sculpt mouse) or
just send events more often, i.e. for less physical motion (e.g. MS Comfort
mouse).
For the latter, you need the right HW of course. The Sculpt mouse has
tactile wheel clicks, so nothing really changes. The Comfort mouse has
continuous motion with no tactile clicks. Similar to the free-wheeling
Logitech mice but without any inertia.
Note that the doc also says that Vista and onwards *always* enable this
feature where available.
An example HID definition looks like this:
Usage Page Generic Desktop (0x01)
Usage Resolution Multiplier (0x48)
Logical Minimum 0
Logical Maximum 1
Physical Minimum 1
Physical Maximum 16
Report Size 2 # in bits
Report Count 1
Feature (Data, Var, Abs)
So the actual bits have values 0 or 1 and that reflects real values 1 or 16.
We've only seen single-bits so far, so there's low-res and hi-res, but
nothing in between.
The multiplier is available for HID usages "Wheel" and "AC Pan" (horiz wheel).
Microsoft suggests that
> Vendors should ship their devices with smooth scrolling disabled and allow
> Windows to enable it. This ensures that the device works like a regular HID
> device on legacy operating systems that do not support smooth scrolling.
(see the wheel doc linked above)
The mice that we tested so far do reset on unplug.
Device Support looks to be all (?) Microsoft mice but nothing else
Not supported:
- Logitech G500s, G303
- Roccat Kone XTD
- all the cheap Lenovo, HP, Dell, Logitech USB mice that come with a
workstation that I could find don't have it.
- Etekcity something something
- Razer Imperator
Supported:
- Microsoft Comfort Optical Mouse 3000 - yes, physical: 1:4
- Microsoft Sculpt Ergonomic Mouse - yes, physical: 1:12
- Microsoft Surface mouse - yes, physical: 1:4
So again, I think this is really just available on Microsoft mice, but
probably all decent MS mice released over the last decade.
Looking at the hardware itself:
- no noticeable notches in the weel
- low-res: 18 events per 360deg rotation (click angle 20 deg)
- high-res: 72 events per 360deg → matches multiplier of 4
- I can feel the notches during wheel turns
- low-res: 24 events per 360 deg rotation (click angle 15 deg)
- horiz wheel is tilt-based, continuous output value 1
- high-res: 24 events per 360deg with value 12 → matches multiplier of 12
- horiz wheel output rate doubles/triples?, values is 3
- It's a touch strip, not a wheel so no notches
- high-res: events have value 4 instead of 1
a bit strange given that it doesn't actually have notches.
Ok, why is this an issue for the current API? First, because the logitech
multiplier used in Harry's patches looks suspiciously like the Resolution
Multiplier so I think we should assume it's the same thing. Nestor, can you
shed some light on that?
- `REL_WHEEL` is defined as the number of notches, emulated where needed.
- `REL_WHEEL_HI_RES` is the movement of the user's finger in microns.
- `WM_MOUSEWHEEL` (Windows) is is a multiple of 120, defined as "the threshold
for action to be taken and one such action"
https://docs.microsoft.com/en-us/windows/desktop/inputdev/wm-mousewheel
If the multiplier is set to M, this means we need an accumulated value of M
until we can claim there was a wheel click. So after enabling the multiplier
and setting it to the maximum (like Windows):
- M units are 15deg rotation → 1 unit is 2620/M micron (see below). This is
the `REL_WHEEL_HI_RES` value.
- wheel diameter 20mm: 15 deg rotation is 2.62mm, 2620 micron (pi * 20mm /
(360deg/15deg))
- For every M units accumulated, send one `REL_WHEEL` event
The problem here is that we've now hardcoded 20mm/15 deg into the kernel and
we have no way of getting the size of the wheel or the click angle into the
kernel.
In userspace we now have to undo the kernel's calculation. If our click angle
is e.g. 20 degree we have to undo the (lossy) calculation from the kernel and
calculate the correct angle instead. This also means the 15 is a hardcoded
option forever and cannot be changed.
In hid-logitech-hidpp.c, the microns per unit is hardcoded per device.
Harry, did you measure those by hand? We'd need to update the kernel for
every device and there are 10 years worth of devices from MS alone.
The multiplier default is 8 which is in the right ballpark, so I'm pretty
sure this is the same as the Resolution Multiplier, just in HID++ lingo. And
given that the 120 magic factor is what Windows uses in the end, I can't
imagine Logitech rolling their own thing here. Nestor?
And we're already fairly inaccurate with the microns anyway. The MX Anywhere
2S has a click angle of 20 degrees (18 stops) and a 17mm wheel, so a wheel
notch is approximately 2.67mm, one event at multiplier 8 (1/8 of a notch)
would be 334 micron. That's only 80% of the fallback value of 406 in the
kernel. Multiplier 6 gives us 445micron (10% off). I'm assuming multiplier 7
doesn't exist because it's not a factor of 120.
Summary:
Best option may be to simply do what Windows is doing, all the HW manufacturers
have to use that approach after all. Switch `REL_WHEEL_HI_RES` to report in
fractions of 120, with 120 being one notch and divide that by the multiplier
for the actual events. So e.g. the Logitech multiplier 8 would send value 15
for each event in hi-res mode. This can be converted in userspace to
whatever userspace needs (combined with a hwdb there that tells you wheel
size/click angle/...).
Conflicts:
include/uapi/linux/input-event-codes.h -> I kept the new
reserved event in the code, so I had to adapt the revert
slightly
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
Documentation/input/event-codes.rst | 11 +----------
include/uapi/linux/input-event-codes.h | 10 ----------
2 files changed, 1 insertion(+), 20 deletions(-)
diff --git a/Documentation/input/event-codes.rst b/Documentation/input/event-codes.rst
index cef220c176a4..a8c0873beb95 100644
--- a/Documentation/input/event-codes.rst
+++ b/Documentation/input/event-codes.rst
@@ -190,16 +190,7 @@ A few EV_REL codes have special meanings:
* REL_WHEEL, REL_HWHEEL:
- These codes are used for vertical and horizontal scroll wheels,
- respectively. The value is the number of "notches" moved on the wheel, the
- physical size of which varies by device. For high-resolution wheels (which
- report multiple events for each notch of movement, or do not have notches)
- this may be an approximation based on the high-resolution scroll events.
-
-* REL_WHEEL_HI_RES:
-
- - If a vertical scroll wheel supports high-resolution scrolling, this code
- will be emitted in addition to REL_WHEEL. The value is the (approximate)
- distance travelled by the user's finger, in microns.
+ respectively.
EV_ABS
------
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h
index 6d180cc60a5d..3eb5a4c3d60a 100644
--- a/include/uapi/linux/input-event-codes.h
+++ b/include/uapi/linux/input-event-codes.h
@@ -716,7 +716,6 @@
* the situation described above.
*/
#define REL_RESERVED 0x0a
-#define REL_WHEEL_HI_RES 0x0b
#define REL_MAX 0x0f
#define REL_CNT (REL_MAX+1)
@@ -753,15 +752,6 @@
#define ABS_MISC 0x28
-/*
- * 0x2e is reserved and should not be used in input drivers.
- * It was used by HID as ABS_MISC+6 and userspace needs to detect if
- * the next ABS_* event is correct or is just ABS_MISC + n.
- * We define here ABS_RESERVED so userspace can rely on it and detect
- * the situation described above.
- */
-#define ABS_RESERVED 0x2e
-
#define ABS_MT_SLOT 0x2f /* MT slot being modified */
#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */
--
2.19.1
^ permalink raw reply related
* [PATCH 6/7] Revert "HID: input: Create a utility class for counting scroll events"
From: Benjamin Tissoires @ 2018-11-21 15:27 UTC (permalink / raw)
To: Dmitry Torokhov, Jiri Kosina, Harry Cutts, Peter Hutterer,
torvalds
Cc: Nestor Lopez Casado, linux-input, linux-kernel,
Benjamin Tissoires
In-Reply-To: <20181121152712.6770-1-benjamin.tissoires@redhat.com>
This reverts commit 1ff2e1a44e02d4bdbb9be67c7d9acc240a67141f.
It turns out the current API is not that compatible with
some Microsoft mice, so better start again from scratch.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/hid-input.c | 45 -----------------------------------------
include/linux/hid.h | 28 -------------------------
2 files changed, 73 deletions(-)
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 28ee2ed88a1a..d6fab5798487 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1841,48 +1841,3 @@ void hidinput_disconnect(struct hid_device *hid)
}
EXPORT_SYMBOL_GPL(hidinput_disconnect);
-/**
- * hid_scroll_counter_handle_scroll() - Send high- and low-resolution scroll
- * events given a high-resolution wheel
- * movement.
- * @counter: a hid_scroll_counter struct describing the wheel.
- * @hi_res_value: the movement of the wheel, in the mouse's high-resolution
- * units.
- *
- * Given a high-resolution movement, this function converts the movement into
- * microns and emits high-resolution scroll events for the input device. It also
- * uses the multiplier from &struct hid_scroll_counter to emit low-resolution
- * scroll events when appropriate for backwards-compatibility with userspace
- * input libraries.
- */
-void hid_scroll_counter_handle_scroll(struct hid_scroll_counter *counter,
- int hi_res_value)
-{
- int low_res_scroll_amount;
- /* Some wheels will rest 7/8ths of a notch from the previous notch
- * after slow movement, so we want the threshold for low-res events to
- * be in the middle of the notches (e.g. after 4/8ths) as opposed to on
- * the notches themselves (8/8ths).
- */
- int threshold = counter->resolution_multiplier / 2;
-
- input_report_rel(counter->dev, REL_WHEEL_HI_RES,
- hi_res_value * counter->microns_per_hi_res_unit);
-
- counter->remainder += hi_res_value;
- if (abs(counter->remainder) >= threshold) {
- /* Add (or subtract) 1 because we want to trigger when the wheel
- * is half-way to the next notch (i.e. scroll 1 notch after a
- * 1/2 notch movement, 2 notches after a 1 1/2 notch movement,
- * etc.).
- */
- low_res_scroll_amount =
- counter->remainder / counter->resolution_multiplier
- + (hi_res_value > 0 ? 1 : -1);
- input_report_rel(counter->dev, REL_WHEEL,
- low_res_scroll_amount);
- counter->remainder -=
- low_res_scroll_amount * counter->resolution_multiplier;
- }
-}
-EXPORT_SYMBOL_GPL(hid_scroll_counter_handle_scroll);
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 387c70df6f29..a355d61940f2 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -1139,34 +1139,6 @@ static inline u32 hid_report_len(struct hid_report *report)
int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
int interrupt);
-
-/**
- * struct hid_scroll_counter - Utility class for processing high-resolution
- * scroll events.
- * @dev: the input device for which events should be reported.
- * @microns_per_hi_res_unit: the amount moved by the user's finger for each
- * high-resolution unit reported by the mouse, in
- * microns.
- * @resolution_multiplier: the wheel's resolution in high-resolution mode as a
- * multiple of its lower resolution. For example, if
- * moving the wheel by one "notch" would result in a
- * value of 1 in low-resolution mode but 8 in
- * high-resolution, the multiplier is 8.
- * @remainder: counts the number of high-resolution units moved since the last
- * low-resolution event (REL_WHEEL or REL_HWHEEL) was sent. Should
- * only be used by class methods.
- */
-struct hid_scroll_counter {
- struct input_dev *dev;
- int microns_per_hi_res_unit;
- int resolution_multiplier;
-
- int remainder;
-};
-
-void hid_scroll_counter_handle_scroll(struct hid_scroll_counter *counter,
- int hi_res_value);
-
/* HID quirks API */
unsigned long hid_lookup_quirk(const struct hid_device *hdev);
int hid_quirks_init(char **quirks_param, __u16 bus, int count);
--
2.19.1
^ permalink raw reply related
* [PATCH 5/7] Revert "HID: logitech: Add function to enable HID++ 1.0 "scrolling acceleration""
From: Benjamin Tissoires @ 2018-11-21 15:27 UTC (permalink / raw)
To: Dmitry Torokhov, Jiri Kosina, Harry Cutts, Peter Hutterer,
torvalds
Cc: Nestor Lopez Casado, linux-input, linux-kernel,
Benjamin Tissoires
In-Reply-To: <20181121152712.6770-1-benjamin.tissoires@redhat.com>
This reverts commit 051dc9b0579602bd63e9df74d0879b5293e71581.
It turns out the current API is not that compatible with
some Microsoft mice, so better start again from scratch.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/hid-logitech-hidpp.c | 47 +++++++++-----------------------
1 file changed, 13 insertions(+), 34 deletions(-)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 7f8218f6ff56..19cc980eebce 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -400,53 +400,32 @@ static void hidpp_prefix_name(char **name, int name_length)
#define HIDPP_SET_LONG_REGISTER 0x82
#define HIDPP_GET_LONG_REGISTER 0x83
-/**
- * hidpp10_set_register_bit() - Sets a single bit in a HID++ 1.0 register.
- * @hidpp_dev: the device to set the register on.
- * @register_address: the address of the register to modify.
- * @byte: the byte of the register to modify. Should be less than 3.
- * Return: 0 if successful, otherwise a negative error code.
- */
-static int hidpp10_set_register_bit(struct hidpp_device *hidpp_dev,
- u8 register_address, u8 byte, u8 bit)
+#define HIDPP_REG_GENERAL 0x00
+
+static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev)
{
struct hidpp_report response;
int ret;
u8 params[3] = { 0 };
ret = hidpp_send_rap_command_sync(hidpp_dev,
- REPORT_ID_HIDPP_SHORT,
- HIDPP_GET_REGISTER,
- register_address,
- NULL, 0, &response);
+ REPORT_ID_HIDPP_SHORT,
+ HIDPP_GET_REGISTER,
+ HIDPP_REG_GENERAL,
+ NULL, 0, &response);
if (ret)
return ret;
memcpy(params, response.rap.params, 3);
- params[byte] |= BIT(bit);
+ /* Set the battery bit */
+ params[0] |= BIT(4);
return hidpp_send_rap_command_sync(hidpp_dev,
- REPORT_ID_HIDPP_SHORT,
- HIDPP_SET_REGISTER,
- register_address,
- params, 3, &response);
-}
-
-
-#define HIDPP_REG_GENERAL 0x00
-
-static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev)
-{
- return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_GENERAL, 0, 4);
-}
-
-#define HIDPP_REG_FEATURES 0x01
-
-/* On HID++ 1.0 devices, high-res scroll was called "scrolling acceleration". */
-static int hidpp10_enable_scrolling_acceleration(struct hidpp_device *hidpp_dev)
-{
- return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_FEATURES, 0, 6);
+ REPORT_ID_HIDPP_SHORT,
+ HIDPP_SET_REGISTER,
+ HIDPP_REG_GENERAL,
+ params, 3, &response);
}
#define HIDPP_REG_BATTERY_STATUS 0x07
--
2.19.1
^ permalink raw reply related
* [PATCH 4/7] Revert "HID: logitech: Enable high-resolution scrolling on Logitech mice"
From: Benjamin Tissoires @ 2018-11-21 15:27 UTC (permalink / raw)
To: Dmitry Torokhov, Jiri Kosina, Harry Cutts, Peter Hutterer,
torvalds
Cc: Nestor Lopez Casado, linux-input, linux-kernel,
Benjamin Tissoires
In-Reply-To: <20181121152712.6770-1-benjamin.tissoires@redhat.com>
This reverts commit d56ca9855bf924f3bc9807a3e42f38539df3f41f.
It turns out the current API is not that compatible with
some Microsoft mice, so better start again from scratch.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/hid-logitech-hidpp.c | 249 +------------------------------
1 file changed, 4 insertions(+), 245 deletions(-)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index fd6a8c325fa0..7f8218f6ff56 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -64,14 +64,6 @@ MODULE_PARM_DESC(disable_tap_to_click,
#define HIDPP_QUIRK_NO_HIDINPUT BIT(23)
#define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24)
#define HIDPP_QUIRK_UNIFYING BIT(25)
-#define HIDPP_QUIRK_HI_RES_SCROLL_1P0 BIT(26)
-#define HIDPP_QUIRK_HI_RES_SCROLL_X2120 BIT(27)
-#define HIDPP_QUIRK_HI_RES_SCROLL_X2121 BIT(28)
-
-/* Convenience constant to check for any high-res support. */
-#define HIDPP_QUIRK_HI_RES_SCROLL (HIDPP_QUIRK_HI_RES_SCROLL_1P0 | \
- HIDPP_QUIRK_HI_RES_SCROLL_X2120 | \
- HIDPP_QUIRK_HI_RES_SCROLL_X2121)
#define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT
@@ -157,7 +149,6 @@ struct hidpp_device {
unsigned long capabilities;
struct hidpp_battery battery;
- struct hid_scroll_counter vertical_wheel_counter;
};
/* HID++ 1.0 error codes */
@@ -1166,101 +1157,6 @@ static int hidpp_battery_get_property(struct power_supply *psy,
return ret;
}
-/* -------------------------------------------------------------------------- */
-/* 0x2120: Hi-resolution scrolling */
-/* -------------------------------------------------------------------------- */
-
-#define HIDPP_PAGE_HI_RESOLUTION_SCROLLING 0x2120
-
-#define CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE 0x10
-
-static int hidpp_hrs_set_highres_scrolling_mode(struct hidpp_device *hidpp,
- bool enabled, u8 *multiplier)
-{
- u8 feature_index;
- u8 feature_type;
- int ret;
- u8 params[1];
- struct hidpp_report response;
-
- ret = hidpp_root_get_feature(hidpp,
- HIDPP_PAGE_HI_RESOLUTION_SCROLLING,
- &feature_index,
- &feature_type);
- if (ret)
- return ret;
-
- params[0] = enabled ? BIT(0) : 0;
- ret = hidpp_send_fap_command_sync(hidpp, feature_index,
- CMD_HI_RESOLUTION_SCROLLING_SET_HIGHRES_SCROLLING_MODE,
- params, sizeof(params), &response);
- if (ret)
- return ret;
- *multiplier = response.fap.params[1];
- return 0;
-}
-
-/* -------------------------------------------------------------------------- */
-/* 0x2121: HiRes Wheel */
-/* -------------------------------------------------------------------------- */
-
-#define HIDPP_PAGE_HIRES_WHEEL 0x2121
-
-#define CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY 0x00
-#define CMD_HIRES_WHEEL_SET_WHEEL_MODE 0x20
-
-static int hidpp_hrw_get_wheel_capability(struct hidpp_device *hidpp,
- u8 *multiplier)
-{
- u8 feature_index;
- u8 feature_type;
- int ret;
- struct hidpp_report response;
-
- ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL,
- &feature_index, &feature_type);
- if (ret)
- goto return_default;
-
- ret = hidpp_send_fap_command_sync(hidpp, feature_index,
- CMD_HIRES_WHEEL_GET_WHEEL_CAPABILITY,
- NULL, 0, &response);
- if (ret)
- goto return_default;
-
- *multiplier = response.fap.params[0];
- return 0;
-return_default:
- *multiplier = 8;
- hid_warn(hidpp->hid_dev,
- "Couldn't get wheel multiplier (error %d), assuming %d.\n",
- ret, *multiplier);
- return ret;
-}
-
-static int hidpp_hrw_set_wheel_mode(struct hidpp_device *hidpp, bool invert,
- bool high_resolution, bool use_hidpp)
-{
- u8 feature_index;
- u8 feature_type;
- int ret;
- u8 params[1];
- struct hidpp_report response;
-
- ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL,
- &feature_index, &feature_type);
- if (ret)
- return ret;
-
- params[0] = (invert ? BIT(2) : 0) |
- (high_resolution ? BIT(1) : 0) |
- (use_hidpp ? BIT(0) : 0);
-
- return hidpp_send_fap_command_sync(hidpp, feature_index,
- CMD_HIRES_WHEEL_SET_WHEEL_MODE,
- params, sizeof(params), &response);
-}
-
/* -------------------------------------------------------------------------- */
/* 0x4301: Solar Keyboard */
/* -------------------------------------------------------------------------- */
@@ -2524,8 +2420,7 @@ static int m560_raw_event(struct hid_device *hdev, u8 *data, int size)
input_report_rel(mydata->input, REL_Y, v);
v = hid_snto32(data[6], 8);
- hid_scroll_counter_handle_scroll(
- &hidpp->vertical_wheel_counter, v);
+ input_report_rel(mydata->input, REL_WHEEL, v);
input_sync(mydata->input);
}
@@ -2653,73 +2548,6 @@ static int g920_get_config(struct hidpp_device *hidpp)
return 0;
}
-/* -------------------------------------------------------------------------- */
-/* High-resolution scroll wheels */
-/* -------------------------------------------------------------------------- */
-
-/**
- * struct hi_res_scroll_info - Stores info on a device's high-res scroll wheel.
- * @product_id: the HID product ID of the device being described.
- * @microns_per_hi_res_unit: the distance moved by the user's finger for each
- * high-resolution unit reported by the device, in
- * 256ths of a millimetre.
- */
-struct hi_res_scroll_info {
- __u32 product_id;
- int microns_per_hi_res_unit;
-};
-
-static struct hi_res_scroll_info hi_res_scroll_devices[] = {
- { /* Anywhere MX */
- .product_id = 0x1017, .microns_per_hi_res_unit = 445 },
- { /* Performance MX */
- .product_id = 0x101a, .microns_per_hi_res_unit = 406 },
- { /* M560 */
- .product_id = 0x402d, .microns_per_hi_res_unit = 435 },
- { /* MX Master 2S */
- .product_id = 0x4069, .microns_per_hi_res_unit = 406 },
-};
-
-static int hi_res_scroll_look_up_microns(__u32 product_id)
-{
- int i;
- int num_devices = sizeof(hi_res_scroll_devices)
- / sizeof(hi_res_scroll_devices[0]);
- for (i = 0; i < num_devices; i++) {
- if (hi_res_scroll_devices[i].product_id == product_id)
- return hi_res_scroll_devices[i].microns_per_hi_res_unit;
- }
- /* We don't have a value for this device, so use a sensible default. */
- return 406;
-}
-
-static int hi_res_scroll_enable(struct hidpp_device *hidpp)
-{
- int ret;
- u8 multiplier;
-
- if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2121) {
- ret = hidpp_hrw_set_wheel_mode(hidpp, false, true, false);
- hidpp_hrw_get_wheel_capability(hidpp, &multiplier);
- } else if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2120) {
- ret = hidpp_hrs_set_highres_scrolling_mode(hidpp, true,
- &multiplier);
- } else /* if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_1P0) */ {
- ret = hidpp10_enable_scrolling_acceleration(hidpp);
- multiplier = 8;
- }
- if (ret)
- return ret;
-
- hidpp->vertical_wheel_counter.resolution_multiplier = multiplier;
- hidpp->vertical_wheel_counter.microns_per_hi_res_unit =
- hi_res_scroll_look_up_microns(hidpp->hid_dev->product);
- hid_info(hidpp->hid_dev, "multiplier = %d, microns = %d\n",
- multiplier,
- hidpp->vertical_wheel_counter.microns_per_hi_res_unit);
- return 0;
-}
-
/* -------------------------------------------------------------------------- */
/* Generic HID++ devices */
/* -------------------------------------------------------------------------- */
@@ -2765,11 +2593,6 @@ static void hidpp_populate_input(struct hidpp_device *hidpp,
wtp_populate_input(hidpp, input, origin_is_hid_core);
else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560)
m560_populate_input(hidpp, input, origin_is_hid_core);
-
- if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) {
- input_set_capability(input, EV_REL, REL_WHEEL_HI_RES);
- hidpp->vertical_wheel_counter.dev = input;
- }
}
static int hidpp_input_configured(struct hid_device *hdev,
@@ -2888,27 +2711,6 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report,
return 0;
}
-static int hidpp_event(struct hid_device *hdev, struct hid_field *field,
- struct hid_usage *usage, __s32 value)
-{
- /* This function will only be called for scroll events, due to the
- * restriction imposed in hidpp_usages.
- */
- struct hidpp_device *hidpp = hid_get_drvdata(hdev);
- struct hid_scroll_counter *counter = &hidpp->vertical_wheel_counter;
- /* A scroll event may occur before the multiplier has been retrieved or
- * the input device set, or high-res scroll enabling may fail. In such
- * cases we must return early (falling back to default behaviour) to
- * avoid a crash in hid_scroll_counter_handle_scroll.
- */
- if (!(hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) || value == 0
- || counter->dev == NULL || counter->resolution_multiplier == 0)
- return 0;
-
- hid_scroll_counter_handle_scroll(counter, value);
- return 1;
-}
-
static int hidpp_initialize_battery(struct hidpp_device *hidpp)
{
static atomic_t battery_no = ATOMIC_INIT(0);
@@ -3120,9 +2922,6 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
if (hidpp->battery.ps)
power_supply_changed(hidpp->battery.ps);
- if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL)
- hi_res_scroll_enable(hidpp);
-
if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input)
/* if the input nodes are already created, we can stop now */
return;
@@ -3308,10 +3107,6 @@ static void hidpp_remove(struct hid_device *hdev)
mutex_destroy(&hidpp->send_mutex);
}
-#define LDJ_DEVICE(product) \
- HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, \
- USB_VENDOR_ID_LOGITECH, (product))
-
static const struct hid_device_id hidpp_devices[] = {
{ /* wireless touchpad */
HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
@@ -3326,39 +3121,10 @@ static const struct hid_device_id hidpp_devices[] = {
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
USB_DEVICE_ID_LOGITECH_T651),
.driver_data = HIDPP_QUIRK_CLASS_WTP },
- { /* Mouse Logitech Anywhere MX */
- LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
- { /* Mouse Logitech Cube */
- LDJ_DEVICE(0x4010), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
- { /* Mouse Logitech M335 */
- LDJ_DEVICE(0x4050), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
- { /* Mouse Logitech M515 */
- LDJ_DEVICE(0x4007), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
{ /* Mouse logitech M560 */
- LDJ_DEVICE(0x402d),
- .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560
- | HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
- { /* Mouse Logitech M705 (firmware RQM17) */
- LDJ_DEVICE(0x101b), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
- { /* Mouse Logitech M705 (firmware RQM67) */
- LDJ_DEVICE(0x406d), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
- { /* Mouse Logitech M720 */
- LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
- { /* Mouse Logitech MX Anywhere 2 */
- LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
- { LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
- { LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
- { LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
- { /* Mouse Logitech MX Anywhere 2S */
- LDJ_DEVICE(0x406a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
- { /* Mouse Logitech MX Master */
- LDJ_DEVICE(0x4041), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
- { LDJ_DEVICE(0x4060), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
- { LDJ_DEVICE(0x4071), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
- { /* Mouse Logitech MX Master 2S */
- LDJ_DEVICE(0x4069), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
- { /* Mouse Logitech Performance MX */
- LDJ_DEVICE(0x101a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
+ HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
+ USB_VENDOR_ID_LOGITECH, 0x402d),
+ .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 },
{ /* Keyboard logitech K400 */
HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
USB_VENDOR_ID_LOGITECH, 0x4024),
@@ -3378,19 +3144,12 @@ static const struct hid_device_id hidpp_devices[] = {
MODULE_DEVICE_TABLE(hid, hidpp_devices);
-static const struct hid_usage_id hidpp_usages[] = {
- { HID_GD_WHEEL, EV_REL, REL_WHEEL },
- { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
-};
-
static struct hid_driver hidpp_driver = {
.name = "logitech-hidpp-device",
.id_table = hidpp_devices,
.probe = hidpp_probe,
.remove = hidpp_remove,
.raw_event = hidpp_raw_event,
- .usage_table = hidpp_usages,
- .event = hidpp_event,
.input_configured = hidpp_input_configured,
.input_mapping = hidpp_input_mapping,
.input_mapped = hidpp_input_mapped,
--
2.19.1
^ permalink raw reply related
* [PATCH 3/7] Revert "HID: logitech: Use LDJ_DEVICE macro for existing Logitech mice"
From: Benjamin Tissoires @ 2018-11-21 15:27 UTC (permalink / raw)
To: Dmitry Torokhov, Jiri Kosina, Harry Cutts, Peter Hutterer,
torvalds
Cc: Nestor Lopez Casado, linux-input, linux-kernel,
Benjamin Tissoires
In-Reply-To: <20181121152712.6770-1-benjamin.tissoires@redhat.com>
This reverts commit 3fe1d6bbcd16f384d2c7dab2caf8e4b2df9ea7e6.
It turns out the current API is not that compatible with
some Microsoft mice, so better start again from scratch.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/hid-logitech-hidpp.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 5f0c080059c6..fd6a8c325fa0 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -3314,11 +3314,13 @@ static void hidpp_remove(struct hid_device *hdev)
static const struct hid_device_id hidpp_devices[] = {
{ /* wireless touchpad */
- LDJ_DEVICE(0x4011),
+ HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
+ USB_VENDOR_ID_LOGITECH, 0x4011),
.driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT |
HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS },
{ /* wireless touchpad T650 */
- LDJ_DEVICE(0x4101),
+ HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
+ USB_VENDOR_ID_LOGITECH, 0x4101),
.driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
{ /* wireless touchpad T651 */
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
@@ -3358,13 +3360,16 @@ static const struct hid_device_id hidpp_devices[] = {
{ /* Mouse Logitech Performance MX */
LDJ_DEVICE(0x101a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
{ /* Keyboard logitech K400 */
- LDJ_DEVICE(0x4024),
+ HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
+ USB_VENDOR_ID_LOGITECH, 0x4024),
.driver_data = HIDPP_QUIRK_CLASS_K400 },
{ /* Solar Keyboard Logitech K750 */
- LDJ_DEVICE(0x4002),
+ HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
+ USB_VENDOR_ID_LOGITECH, 0x4002),
.driver_data = HIDPP_QUIRK_CLASS_K750 },
- { LDJ_DEVICE(HID_ANY_ID) },
+ { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
+ USB_VENDOR_ID_LOGITECH, HID_ANY_ID)},
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL),
.driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS},
--
2.19.1
^ permalink raw reply related
* [PATCH 2/7] Revert "HID: logitech: fix a used uninitialized GCC warning"
From: Benjamin Tissoires @ 2018-11-21 15:27 UTC (permalink / raw)
To: Dmitry Torokhov, Jiri Kosina, Harry Cutts, Peter Hutterer,
torvalds
Cc: Nestor Lopez Casado, linux-input, linux-kernel,
Benjamin Tissoires
In-Reply-To: <20181121152712.6770-1-benjamin.tissoires@redhat.com>
This reverts commit 5fe2ccbef9d7aecf5c4402c753444f1a12096cfd.
It turns out the current API is not that compatible with
some Microsoft mice, so better start again from scratch.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/hid-logitech-hidpp.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index f01280898b24..5f0c080059c6 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -1231,6 +1231,7 @@ static int hidpp_hrw_get_wheel_capability(struct hidpp_device *hidpp,
*multiplier = response.fap.params[0];
return 0;
return_default:
+ *multiplier = 8;
hid_warn(hidpp->hid_dev,
"Couldn't get wheel multiplier (error %d), assuming %d.\n",
ret, *multiplier);
@@ -2695,7 +2696,7 @@ static int hi_res_scroll_look_up_microns(__u32 product_id)
static int hi_res_scroll_enable(struct hidpp_device *hidpp)
{
int ret;
- u8 multiplier = 8;
+ u8 multiplier;
if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2121) {
ret = hidpp_hrw_set_wheel_mode(hidpp, false, true, false);
@@ -2703,9 +2704,10 @@ static int hi_res_scroll_enable(struct hidpp_device *hidpp)
} else if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2120) {
ret = hidpp_hrs_set_highres_scrolling_mode(hidpp, true,
&multiplier);
- } else /* if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_1P0) */
+ } else /* if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_1P0) */ {
ret = hidpp10_enable_scrolling_acceleration(hidpp);
-
+ multiplier = 8;
+ }
if (ret)
return ret;
--
2.19.1
^ permalink raw reply related
* [PATCH 1/7] Revert "HID: input: simplify/fix high-res scroll event handling"
From: Benjamin Tissoires @ 2018-11-21 15:27 UTC (permalink / raw)
To: Dmitry Torokhov, Jiri Kosina, Harry Cutts, Peter Hutterer,
torvalds
Cc: Nestor Lopez Casado, linux-input, linux-kernel,
Benjamin Tissoires
In-Reply-To: <20181121152712.6770-1-benjamin.tissoires@redhat.com>
This reverts commit 044ee890286153a1aefb40cb8b6659921aecb38b.
It turns out the current API is not that compatible with
some Microsoft mice, so better start again from scratch.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
drivers/hid/hid-input.c | 43 +++++++++++++++++++++--------------------
1 file changed, 22 insertions(+), 21 deletions(-)
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 44ea8e7c71a9..28ee2ed88a1a 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1858,30 +1858,31 @@ EXPORT_SYMBOL_GPL(hidinput_disconnect);
void hid_scroll_counter_handle_scroll(struct hid_scroll_counter *counter,
int hi_res_value)
{
- int low_res_value, remainder, multiplier;
+ int low_res_scroll_amount;
+ /* Some wheels will rest 7/8ths of a notch from the previous notch
+ * after slow movement, so we want the threshold for low-res events to
+ * be in the middle of the notches (e.g. after 4/8ths) as opposed to on
+ * the notches themselves (8/8ths).
+ */
+ int threshold = counter->resolution_multiplier / 2;
input_report_rel(counter->dev, REL_WHEEL_HI_RES,
hi_res_value * counter->microns_per_hi_res_unit);
- /*
- * Update the low-res remainder with the high-res value,
- * but reset if the direction has changed.
- */
- remainder = counter->remainder;
- if ((remainder ^ hi_res_value) < 0)
- remainder = 0;
- remainder += hi_res_value;
-
- /*
- * Then just use the resolution multiplier to see if
- * we should send a low-res (aka regular wheel) event.
- */
- multiplier = counter->resolution_multiplier;
- low_res_value = remainder / multiplier;
- remainder -= low_res_value * multiplier;
- counter->remainder = remainder;
-
- if (low_res_value)
- input_report_rel(counter->dev, REL_WHEEL, low_res_value);
+ counter->remainder += hi_res_value;
+ if (abs(counter->remainder) >= threshold) {
+ /* Add (or subtract) 1 because we want to trigger when the wheel
+ * is half-way to the next notch (i.e. scroll 1 notch after a
+ * 1/2 notch movement, 2 notches after a 1 1/2 notch movement,
+ * etc.).
+ */
+ low_res_scroll_amount =
+ counter->remainder / counter->resolution_multiplier
+ + (hi_res_value > 0 ? 1 : -1);
+ input_report_rel(counter->dev, REL_WHEEL,
+ low_res_scroll_amount);
+ counter->remainder -=
+ low_res_scroll_amount * counter->resolution_multiplier;
+ }
}
EXPORT_SYMBOL_GPL(hid_scroll_counter_handle_scroll);
--
2.19.1
^ permalink raw reply related
* [PATCH 0/7] HID: revert the Logitech High Resolution wheel support
From: Benjamin Tissoires @ 2018-11-21 15:27 UTC (permalink / raw)
To: Dmitry Torokhov, Jiri Kosina, Harry Cutts, Peter Hutterer,
torvalds
Cc: Nestor Lopez Casado, linux-input, linux-kernel,
Benjamin Tissoires
It turns out that the implementation of the high resolution support of
Logitech wheels is rather incompatible with the mice from Microsoft.
We had a lengthy discussion off-list and the summary is quoted in 7/7.
The TL;DR, we need to revert the current series before it gets out in
a released kernel and work on a better approach for 4.21.
This patch series has informally been acked by Dmitry, Harry, Jiri, Nestor
and Peter, but I wouldn't mind a public ack before I push this to
the for-linus branch.
Dmitry, I chose to also revert "Input: Add the `REL_WHEEL_HI_RES` event code"
as the documentation needs to be updated.
I would understand if you rather keep the patch that way and we just update
the doc. This would help synchronizing the trees. So please tell me if you
want 7/7 in the series or not (I'll reshuffle the commit message to have
the summary from Peter).
Cheers,
Benjamin
Benjamin Tissoires (7):
Revert "HID: input: simplify/fix high-res scroll event handling"
Revert "HID: logitech: fix a used uninitialized GCC warning"
Revert "HID: logitech: Use LDJ_DEVICE macro for existing Logitech
mice"
Revert "HID: logitech: Enable high-resolution scrolling on Logitech
mice"
Revert "HID: logitech: Add function to enable HID++ 1.0 "scrolling
acceleration""
Revert "HID: input: Create a utility class for counting scroll events"
Revert "Input: Add the `REL_WHEEL_HI_RES` event code"
Documentation/input/event-codes.rst | 11 +-
drivers/hid/hid-input.c | 44 ----
drivers/hid/hid-logitech-hidpp.c | 309 +++----------------------
include/linux/hid.h | 28 ---
include/uapi/linux/input-event-codes.h | 10 -
5 files changed, 28 insertions(+), 374 deletions(-)
--
2.19.1
^ permalink raw reply
* [PATCH] Input: i8042 add of_node_put()
From: Yangtao Li @ 2018-11-21 14:35 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel, Yangtao Li
use of_node_put() to release the refcount.
Signed-off-by: Yangtao Li <tiny.windzz@gmail.com>
---
drivers/input/serio/i8042-sparcio.h | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h
index 796289846204..5495bc035518 100644
--- a/drivers/input/serio/i8042-sparcio.h
+++ b/drivers/input/serio/i8042-sparcio.h
@@ -108,18 +108,21 @@ static struct platform_driver sparc_i8042_driver = {
static int __init i8042_platform_init(void)
{
+ int rc;
struct device_node *root = of_find_node_by_path("/");
if (!strcmp(root->name, "SUNW,JavaStation-1")) {
/* Hardcoded values for MrCoffee. */
i8042_kbd_irq = i8042_aux_irq = 13 | 0x20;
kbd_iobase = ioremap(0x71300060, 8);
- if (!kbd_iobase)
- return -ENODEV;
+ if (!kbd_iobase){
+ rc = -ENODEV;
+ goto out;
+ }
} else {
- int err = platform_driver_register(&sparc_i8042_driver);
- if (err)
- return err;
+ rc = platform_driver_register(&sparc_i8042_driver);
+ if (rc)
+ goto out;
if (i8042_kbd_irq == -1 ||
i8042_aux_irq == -1) {
@@ -127,13 +130,18 @@ static int __init i8042_platform_init(void)
of_iounmap(kbd_res, kbd_iobase, 8);
kbd_iobase = (void __iomem *) NULL;
}
- return -ENODEV;
+ rc = -ENODEV;
+ goto out;
}
}
i8042_reset = I8042_RESET_ALWAYS;
- return 0;
+ rc = 0;
+out:
+ of_node_put(root);
+
+ return rc;
}
static inline void i8042_platform_exit(void)
@@ -142,6 +150,8 @@ static inline void i8042_platform_exit(void)
if (strcmp(root->name, "SUNW,JavaStation-1"))
platform_driver_unregister(&sparc_i8042_driver);
+
+ of_node_put(root);
}
#else /* !CONFIG_PCI */
--
2.17.0
^ permalink raw reply related
* [PATCH] Input: sparcspkr add of_node_put()
From: Yangtao Li @ 2018-11-21 13:28 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel, Yangtao Li
of_find_node_by_path() acquires a reference to the node
returned by it and that reference needs to be dropped by its caller.
bl_idle_init() doesn't do that, so fix it.
Signed-off-by: Yangtao Li <tiny.windzz@gmail.com>
---
drivers/input/misc/sparcspkr.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index 4a5afc7fe96e..dc121fbbd3e1 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -205,11 +205,11 @@ static int bbc_beep_probe(struct platform_device *op)
info = &state->u.bbc;
info->clock_freq = of_getintprop_default(dp, "clock-frequency", 0);
if (!info->clock_freq)
- goto out_free;
+ goto out_put_node;
info->regs = of_ioremap(&op->resource[0], 0, 6, "bbc beep");
if (!info->regs)
- goto out_free;
+ goto out_put_node;
platform_set_drvdata(op, state);
@@ -217,11 +217,14 @@ static int bbc_beep_probe(struct platform_device *op)
if (err)
goto out_clear_drvdata;
+ of_node_put(dp);
+
return 0;
out_clear_drvdata:
of_iounmap(&op->resource[0], info->regs, 6);
-
+out_put_node:
+ of_node_put(dp);
out_free:
kfree(state);
out_err:
--
2.17.0
^ permalink raw reply related
* Re: [PATCH] ACPI / platform: Add SMB0001 HID to forbidden_id_list
From: Rafael J. Wysocki @ 2018-11-21 10:43 UTC (permalink / raw)
To: Hans de Goede
Cc: Len Brown, Lukas Kahnert, Marc, linux-acpi, linux-input, stable
In-Reply-To: <df516936-89f4-0fc9-1904-1a719bcd13fe@redhat.com>
On Wednesday, November 21, 2018 11:37:22 AM CET Hans de Goede wrote:
> HI,
>
> On 19-11-18 19:06, Hans de Goede wrote:
> > Many HP AMD based laptops contain an SMB0001 device like this:
> >
> > Device (SMBD)
> > {
> > Name (_HID, "SMB0001") // _HID: Hardware ID
> > Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
> > {
> > IO (Decode16,
> > 0x0B20, // Range Minimum
> > 0x0B20, // Range Maximum
> > 0x20, // Alignment
> > 0x20, // Length
> > )
> > IRQ (Level, ActiveLow, Shared, )
> > {7}
> > })
> > }
> >
> > The legacy style IRQ resource here causes acpi_dev_get_irqresource() to
> > be called with legacy=true and this message to show in dmesg:
> > ACPI: IRQ 7 override to edge, high
> >
> > This causes issues when later on the AMD0030 GPIO device gets enumerated:
> >
> > Device (GPIO)
> > {
> > Name (_HID, "AMDI0030") // _HID: Hardware ID
> > Name (_CID, "AMDI0030") // _CID: Compatible ID
> > Name (_UID, Zero) // _UID: Unique ID
> > Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
> > {
> > Name (RBUF, ResourceTemplate ()
> > {
> > Interrupt (ResourceConsumer, Level, ActiveLow, Shared, ,, )
> > {
> > 0x00000007,
> > }
> > Memory32Fixed (ReadWrite,
> > 0xFED81500, // Address Base
> > 0x00000400, // Address Length
> > )
> > })
> > Return (RBUF) /* \_SB_.GPIO._CRS.RBUF */
> > }
> > }
> >
> > Now acpi_dev_get_irqresource() gets called with legacy=false, but because
> > of the earlier override of the trigger-type acpi_register_gsi() returns
> > -EBUSY (because we try to register the same interrupt with a different
> > trigger-type) and we end up setting IORESOURCE_DISABLED in the flags.
> >
> > The setting of IORESOURCE_DISABLED causes platform_get_irq() to call
> > acpi_irq_get() which is not implemented on x86 and returns -EINVAL.
> > resulting in the following in dmesg:
> >
> > amd_gpio AMDI0030:00: Failed to get gpio IRQ: -22
> > amd_gpio: probe of AMDI0030:00 failed with error -22
> >
> > The SMB0001 is a "virtual" device in the sense that the only way the OS
> > interacts with it is through calling a couple of methods to do SMBus
> > transfers. As such it is weird that it has IO and IRQ resources at all,
> > because the driver for it is not expected to ever access the hardware
> > directly.
> >
> > The Linux driver for the SMB0001 device directly binds to the acpi_device
> > through the acpi_bus, so we do not need to instantiate a platform_device
> > for this ACPI device. This commit adds the SMB0001 HID to the
> > forbidden_id_list, avoiding the instantiating of a platform_device for it.
> > Not instantiating a platform_device means we will no longer call
> > acpi_dev_get_irqresource() for the legacy IRQ resource fixing the probe of
> > the AMDI0030 device failing.
> >
> > BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1644013
> > BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=198715
> > BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199523
> > Reported-by: Lukas Kahnert <openproggerfreak@gmail.com>
> > Tested-by: Marc <suaefar@googlemail.com>
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>
> A quick status update on this, I've got confirmation from 4 different users
> that this fixes the touchscreen not working on various models AMD based
> HP laptops.
>
> As such it would be nice to get this into 4.20 as a bugfix.
I'm going to queue it up.
Thanks,
Rafael
^ permalink raw reply
* Re: [PATCH] ACPI / platform: Add SMB0001 HID to forbidden_id_list
From: Hans de Goede @ 2018-11-21 10:37 UTC (permalink / raw)
To: Rafael J . Wysocki, Len Brown
Cc: Lukas Kahnert, Marc, linux-acpi, linux-input, stable
In-Reply-To: <20181119180601.962-1-hdegoede@redhat.com>
HI,
On 19-11-18 19:06, Hans de Goede wrote:
> Many HP AMD based laptops contain an SMB0001 device like this:
>
> Device (SMBD)
> {
> Name (_HID, "SMB0001") // _HID: Hardware ID
> Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
> {
> IO (Decode16,
> 0x0B20, // Range Minimum
> 0x0B20, // Range Maximum
> 0x20, // Alignment
> 0x20, // Length
> )
> IRQ (Level, ActiveLow, Shared, )
> {7}
> })
> }
>
> The legacy style IRQ resource here causes acpi_dev_get_irqresource() to
> be called with legacy=true and this message to show in dmesg:
> ACPI: IRQ 7 override to edge, high
>
> This causes issues when later on the AMD0030 GPIO device gets enumerated:
>
> Device (GPIO)
> {
> Name (_HID, "AMDI0030") // _HID: Hardware ID
> Name (_CID, "AMDI0030") // _CID: Compatible ID
> Name (_UID, Zero) // _UID: Unique ID
> Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
> {
> Name (RBUF, ResourceTemplate ()
> {
> Interrupt (ResourceConsumer, Level, ActiveLow, Shared, ,, )
> {
> 0x00000007,
> }
> Memory32Fixed (ReadWrite,
> 0xFED81500, // Address Base
> 0x00000400, // Address Length
> )
> })
> Return (RBUF) /* \_SB_.GPIO._CRS.RBUF */
> }
> }
>
> Now acpi_dev_get_irqresource() gets called with legacy=false, but because
> of the earlier override of the trigger-type acpi_register_gsi() returns
> -EBUSY (because we try to register the same interrupt with a different
> trigger-type) and we end up setting IORESOURCE_DISABLED in the flags.
>
> The setting of IORESOURCE_DISABLED causes platform_get_irq() to call
> acpi_irq_get() which is not implemented on x86 and returns -EINVAL.
> resulting in the following in dmesg:
>
> amd_gpio AMDI0030:00: Failed to get gpio IRQ: -22
> amd_gpio: probe of AMDI0030:00 failed with error -22
>
> The SMB0001 is a "virtual" device in the sense that the only way the OS
> interacts with it is through calling a couple of methods to do SMBus
> transfers. As such it is weird that it has IO and IRQ resources at all,
> because the driver for it is not expected to ever access the hardware
> directly.
>
> The Linux driver for the SMB0001 device directly binds to the acpi_device
> through the acpi_bus, so we do not need to instantiate a platform_device
> for this ACPI device. This commit adds the SMB0001 HID to the
> forbidden_id_list, avoiding the instantiating of a platform_device for it.
> Not instantiating a platform_device means we will no longer call
> acpi_dev_get_irqresource() for the legacy IRQ resource fixing the probe of
> the AMDI0030 device failing.
>
> BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1644013
> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=198715
> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199523
> Reported-by: Lukas Kahnert <openproggerfreak@gmail.com>
> Tested-by: Marc <suaefar@googlemail.com>
> Cc: stable@vger.kernel.org
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
A quick status update on this, I've got confirmation from 4 different users
that this fixes the touchscreen not working on various models AMD based
HP laptops.
As such it would be nice to get this into 4.20 as a bugfix.
Regards,
Hans
> ---
> drivers/acpi/acpi_platform.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c
> index eaa60c94205a..1f32caa87686 100644
> --- a/drivers/acpi/acpi_platform.c
> +++ b/drivers/acpi/acpi_platform.c
> @@ -30,6 +30,7 @@ static const struct acpi_device_id forbidden_id_list[] = {
> {"PNP0200", 0}, /* AT DMA Controller */
> {"ACPI0009", 0}, /* IOxAPIC */
> {"ACPI000A", 0}, /* IOAPIC */
> + {"SMB0001", 0}, /* ACPI SMBUS virtual device */
> {"", 0},
> };
>
>
^ permalink raw reply
* Re: [PATCH] HID: Add quirk for Primax PIXART OEM mice
From: Jiri Kosina @ 2018-11-20 12:08 UTC (permalink / raw)
To: Sebastian Parschauer; +Cc: Benjamin Tissoires, linux-input, linux-usb, stable
In-Reply-To: <20181120062508.4567-1-sparschauer@suse.de>
On Tue, 20 Nov 2018, Sebastian Parschauer wrote:
> The PixArt OEM mice are known for disconnecting every minute in
> runlevel 1 or 3 if they are not always polled. So add quirk
> ALWAYS_POLL for two Primax mice as well.
>
> 0x4e22 is the Dell MS111-P and 0x4d0f is the unbranded HP Portia
> mouse HP 697738-001. Both were built until approx. 2014.
> Those were the standard mice from those vendors and are still
> around - even as new old stock.
>
> Reference: https://github.com/sriemer/fix-linux-mouse/issues/11
>
> Signed-off-by: Sebastian Parschauer <sparschauer@suse.de>
> CC: stable@vger.kernel.org
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* [PATCH] HID: Add quirk for Primax PIXART OEM mice
From: Sebastian Parschauer @ 2018-11-20 6:25 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires
Cc: linux-input, linux-usb, Sebastian Parschauer, stable
The PixArt OEM mice are known for disconnecting every minute in
runlevel 1 or 3 if they are not always polled. So add quirk
ALWAYS_POLL for two Primax mice as well.
0x4e22 is the Dell MS111-P and 0x4d0f is the unbranded HP Portia
mouse HP 697738-001. Both were built until approx. 2014.
Those were the standard mice from those vendors and are still
around - even as new old stock.
Reference: https://github.com/sriemer/fix-linux-mouse/issues/11
Signed-off-by: Sebastian Parschauer <sparschauer@suse.de>
CC: stable@vger.kernel.org
---
drivers/hid/hid-ids.h | 2 ++
drivers/hid/hid-quirks.c | 2 ++
2 files changed, 4 insertions(+)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 2114ac647bef..ed35c9a9a110 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -1210,6 +1210,8 @@
#define USB_DEVICE_ID_PRIMAX_MOUSE_4D22 0x4d22
#define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05
#define USB_DEVICE_ID_PRIMAX_REZEL 0x4e72
+#define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F 0x4d0f
+#define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22 0x4e22
#define USB_VENDOR_ID_RISO_KAGAKU 0x1294 /* Riso Kagaku Corp. */
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index d82e5ab48837..c85a79986b6a 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -130,6 +130,8 @@ static const struct hid_device_id hid_quirks[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN), HID_QUIRK_NO_INIT_REPORTS },
{ HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS), HID_QUIRK_NOGET },
{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001), HID_QUIRK_NOGET },
{ HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3003), HID_QUIRK_NOGET },
--
2.13.7
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox