* [PATCH v2 2/5] Create a utility class for counting scroll events
From: Harry Cutts @ 2018-08-30 21:56 UTC (permalink / raw)
To: linux-input, LKML
Cc: Jiri Kosina, Dmitry Torokhov, Benjamin Tissoires, Harry Cutts,
Jiri Kosina
In-Reply-To: <20180830215622.47550-1-hcutts@chromium.org>
To avoid code duplication, this class counts high-resolution scroll
movements and emits the legacy low-resolution events when appropriate.
Drivers should be able to create one instance for each scroll wheel that
they need to handle.
Signed-off-by: Harry Cutts <hcutts@chromium.org>
---
Changes in v2: None
drivers/hid/hid-input.c | 45 +++++++++++++++++++++++++++++++++++++++++
include/linux/hid.h | 28 +++++++++++++++++++++++++
2 files changed, 73 insertions(+)
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 4e94ea3e280a..6e84e7b9afcb 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1826,3 +1826,48 @@ 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 834e6461a690..037e37b0b0e6 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -1138,6 +1138,34 @@ 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.0.rc0.228.g281dcd1b4d0-goog
^ permalink raw reply related
* [PATCH v2 1/5] Add the `REL_WHEEL_HI_RES` event code
From: Harry Cutts @ 2018-08-30 21:56 UTC (permalink / raw)
To: linux-input, LKML
Cc: Jiri Kosina, Dmitry Torokhov, Benjamin Tissoires, Harry Cutts,
linux-doc, Jonathan Corbet
In-Reply-To: <20180830215622.47550-1-hcutts@chromium.org>
This event code represents scroll reports from high-resolution wheels,
and will be used by future patches in this series. See the linux-input
"Reporting high-resolution scroll events" thread [0] for more details.
[0]: https://www.spinics.net/lists/linux-input/msg57380.html
Signed-off-by: Harry Cutts <hcutts@chromium.org>
---
Changes in v2: None
Documentation/input/event-codes.rst | 11 ++++++++++-
include/uapi/linux/input-event-codes.h | 1 +
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/Documentation/input/event-codes.rst b/Documentation/input/event-codes.rst
index a8c0873beb95..cef220c176a4 100644
--- a/Documentation/input/event-codes.rst
+++ b/Documentation/input/event-codes.rst
@@ -190,7 +190,16 @@ 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 "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.
EV_ABS
------
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h
index 53fbae27b280..dad8d3890a3a 100644
--- a/include/uapi/linux/input-event-codes.h
+++ b/include/uapi/linux/input-event-codes.h
@@ -708,6 +708,7 @@
#define REL_DIAL 0x07
#define REL_WHEEL 0x08
#define REL_MISC 0x09
+#define REL_WHEEL_HI_RES 0x0a
#define REL_MAX 0x0f
#define REL_CNT (REL_MAX+1)
--
2.19.0.rc0.228.g281dcd1b4d0-goog
^ permalink raw reply related
* [PATCH v2 0/5] Add support for high-resolution scrolling on Logitech mice
From: Harry Cutts @ 2018-08-30 21:56 UTC (permalink / raw)
To: linux-input, LKML
Cc: Jiri Kosina, Dmitry Torokhov, Benjamin Tissoires, Harry Cutts,
linux-doc, Jonathan Corbet, Jiri Kosina
Hi everyone,
This is v2 of the patch set adding support for high-resolution scroll
wheels on Logitech mice. See the linux-input "Reporting high-resolution
scroll events" thread [0] for previous discussion of the evdev changes.
I would love to hear your feedback.
Thanks,
Harry Cutts
Chrome OS Touch/Input team
[0]: https://www.spinics.net/lists/linux-input/msg57380.html
Changes in v2:
* Changed the REL_WHEEL_HI_RES code to use micrometres (a.k.a. microns)
as its units, instead of 256ths of a millimetre.
* Removed support for mice connecting over Bluetooth, due to a bug where
the mouse's high-res mode and the driver's settings get out of sync
when the mouse is power cycled.
* Moved the creation of the HID++ 1.0 function and the refactor to use
the LDJ_DEVICE macro into separate patches.
* Added a couple of explanatory comments to the Logitech driver.
Harry Cutts (5):
Add the `REL_WHEEL_HI_RES` event code
Create a utility class for counting scroll events
Add function to enable HID++ 1.0 "scrolling acceleration"
Enable high-resolution scrolling on Logitech mice
Use LDJ_DEVICE macro for existing Logitech mice
Documentation/input/event-codes.rst | 11 +-
drivers/hid/hid-input.c | 45 ++++
drivers/hid/hid-logitech-hidpp.c | 311 ++++++++++++++++++++++---
include/linux/hid.h | 28 +++
include/uapi/linux/input-event-codes.h | 1 +
5 files changed, 368 insertions(+), 28 deletions(-)
--
2.19.0.rc0.228.g281dcd1b4d0-goog
^ permalink raw reply
* Re: [PATCH 3/3] Enable high-resolution scrolling on Logitech mice
From: Harry Cutts @ 2018-08-30 20:37 UTC (permalink / raw)
To: benjamin.tissoires
Cc: Nestor Lopez Casado, linux-input, linux-kernel, Dmitry Torokhov,
jikos
In-Reply-To: <CAO-hwJ+tb6XdEM76r0jxBfCx2r_PqQp9T5=A2ALociyHOKUeMg@mail.gmail.com>
Hi Benjamin,
On Thu, 30 Aug 2018 at 00:18, Benjamin Tissoires
<benjamin.tissoires@redhat.com> wrote:
>> On Thu, Aug 30, 2018 at 1:06 AM Harry Cutts <hcutts@chromium.org> wrote:
> > > The conversion input_report_rel(... REL_WHEEL,...) to
> > > hid_scroll_counter_handle_scroll() should be dealt in a separate
> > > patch.
> >
> > OK, I'll do that in v2, but might I ask why? I don't see how this
> > particular hunk is special.
>
> I tend to consider that existing code rewrite need to be in their
> special commit, especially if the change isn't supposed to change the
> behaviour. This is my personal taste in case something goes wrong and
> (in this case) a m560 suddenly starts complaining about an issue with
> this mouse.
> I wouldn't mind too much if you rather keep the
> hid_scroll_counter_handle_scroll() introduction to this commit though.
Yes, I see the reasoning for that, but this hunk is pretty tied to the
main change in that scrolling on the M560 would be 8x too fast without
it. I'll keep it in the same one, if you don't mind.
> > [snip]
> > Yes, it seems to work fine without it (at least for the MX Master 2S).
> > Unfortunately, while testing this I encountered a bug with high-res
> > scrolling over Bluetooth. (It seems that if you turn off the MX Master
> > 2S while it's connected over Bluetooth, we don't detect that and
> > remove the input device, meaning that when it reconnects the driver
> > thinks it's in high-res mode but the mouse is in low-res.) I'm
> > investigating, but in the meantime I'll remove the Bluetooth support
> > from v2 and add it back in later.
>
> As far as I can see, the MX Master 2S is connected over BLE. Bluez
> keeps the uhid node opened (and thus the existing bluetooth HID
> device) to be able to reconnect faster.
> I would suppose you should get notified in the connect event of a
> reconnection, but it doesn't seem to be the case.
>
> Nestor, is there any event emitted by the mouse when it gets
> reconnected over BLE or is that a bluez issue?
Ah, interesting. The MX Master 2S is indeed using BLE, and testing
with another Logitech BLE mouse (the M585) also leaves the input
device around. I think this is something Logitech-specific, though, as
the Microsoft Surface Precision mouse (also BLE) does have its input
device removed when it turns off. I notice that btmon does show
"device disconnected" and "device connected" events when I turn the
M585 on and off; maybe we need to plumb those through to the driver.
We've decided to delay Bluetooth support for high-res scrolling until
the Chrome OS Bluetooth stack is more stable.
Harry Cutts
Chrome OS Touch/Input team
^ permalink raw reply
* [PATCH] Input: tca8418: remove redundant variable max_keys
From: Colin King @ 2018-08-30 12:39 UTC (permalink / raw)
To: Dmitry Torokhov, Damien Riegel, linux-input; +Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
Variable max_keys is being assigned but is never used hence it is
redundant and can be removed.
Cleans up clang warning:
variable 'max_keys' set but not used [-Wunused-but-set-variable]
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
drivers/input/keyboard/tca8418_keypad.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c
index 6da607d3b811..3bbd7e652533 100644
--- a/drivers/input/keyboard/tca8418_keypad.c
+++ b/drivers/input/keyboard/tca8418_keypad.c
@@ -266,7 +266,7 @@ static int tca8418_keypad_probe(struct i2c_client *client,
struct tca8418_keypad *keypad_data;
struct input_dev *input;
u32 rows = 0, cols = 0;
- int error, row_shift, max_keys;
+ int error, row_shift;
u8 reg;
/* Check i2c driver capabilities */
@@ -291,7 +291,6 @@ static int tca8418_keypad_probe(struct i2c_client *client,
}
row_shift = get_count_order(cols);
- max_keys = rows << row_shift;
/* Allocate memory for keypad_data and input device */
keypad_data = devm_kzalloc(dev, sizeof(*keypad_data), GFP_KERNEL);
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v6 0/2] Input: Add Cypress Gen5 Touchscreen driver
From: Benjamin Tissoires @ 2018-08-30 7:24 UTC (permalink / raw)
To: mylene.josserand
Cc: Dmitry Torokhov, Rob Herring, mark.rutland, mylene.josserand,
thomas.petazzoni, maxime.ripard, lkml, devicetree,
open list:HID CORE LAYER
In-Reply-To: <20180830091235.6fff7b7d@dell-desktop.home>
On Thu, Aug 30, 2018 at 9:12 AM Mylène Josserand
<mylene.josserand@bootlin.com> wrote:
>
> Hello Dmitry,
>
> On Mon, 13 Aug 2018 08:36:32 -0700
> Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
>
> > Hi Mylène,
> >
> > On Mon, Aug 13, 2018 at 8:24 AM Mylène Josserand
> > <mylene.josserand@bootlin.com> wrote:
> > >
> > > Hi Dmitry,
> > >
> > > On Tue, 24 Jul 2018 10:40:53 -0700
> > > Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> > >
> > > > Hi Mylène,
> > > >
> > > > On Tue, Jul 24, 2018 at 03:00:46PM +0200, Mylène Josserand wrote:
> > > > > Hello Dmitry,
> > > > >
> > > > > On Wed, 4 Jul 2018 16:21:58 +0000
> > > > > Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> > > > >
> > > > > > Hi Mylène,
> > > > > >
> > > > > > On Tue, Jul 03, 2018 at 11:43:07AM +0200, Mylène Josserand wrote:
> > > > > > > Hello,
> > > > > > >
> > > > > > > Here is a V6 series to add the driver of the touchscreen Cypress,
> > > > > > > TrueTouch Generation 5.
> > > > > > > Based on v4.18-rc3.
> > > > > > >
> > > > > > > This patch series has already been posted in several iterations:
> > > > > > > - v1: Sent on 2017/05/29
> > > > > > > - v2: Sent on 2017/08/18
> > > > > > > - v3: Sent on 2017/09/27
> > > > > > > - v4: Sent on 2017/12/01
> > > > > > > - v5: Sent on 2017/12/20
> > > > > > >
> > > > > > > I did not have any comments the last 4 versions.
> > > > > > > And no reviews on my v5 during 6 months. Could I have any updates
> > > > > > > or feedback on my series to know why it is not merged (to be able to
> > > > > > > correct what is wrong)?
> > > > > >
> > > > > > Sorry, I must have missed the v5, sorry about that.
> > > > > >
> > > > > > I probably asked this question before, but just to make sure - I see
> > > > > > references to HID in the patch - the device is really not HID
> > > > > > compatible? Is there any hope it could be made work with i2c-hid +
> > > > > > hid-multitouch?
> > > > > >
> > > > > > Thanks.
> > > > > >
> > > > >
> > > > > I have checked and, for what I have seen, all the HID descriptor stuff
> > > > > is HID compliant. We could definitely use i2c-hid and hid-multitouch
> > > > > (there is the "hid-cypress" driver that exists also).
> > > > >
> > > > > The only problem is that this touchscreen has two modes: a bootloader
> > > > > mode and an application mode (which is the one where we can send
> > > > > HID commands). After a power-on-reset, it is always in "bootloader"
> > > > > mode so we need to send some commands (called "bootloader commands") to
> > > > > switch to application mode.
> > > >
> > > > Is this a documented or observed behavior? In my practice devices (I am
> > > > talking in general, not about Cypress) that have proper configuration
> > > > loaded and that were brought up with appropriate power up sequence and
> > > > timings automatically switch to application mode. They only end up in
> > > > bootloader mode when proper power up sequence is not respected and they
> > > > are unhappy.
> > >
> > > I have checked and indeed, if everything is correctly performed, the
> > > bootloader has a timeout to switch to application mode.
> > > The datasheet says that this timeout can be configured and the "0" value
> > > means that the bootloader will never automatically switch to application
> > > unless a bootloader command is sent.
> > >
> > > In our case, you were right, after a timeout, the touchscreen is
> > > correctly switching to Application mode. Great news!
> > >
> > > >
> > > > > These commands are not HID-compliant as the
> > > > > datasheet indicates:
> > > > >
> > > > > "Bootloader commands are not HID-over-I2C compliant."
> > > >
> > > > Any chance you could share the datasheet?
> > >
> > > Sorry, it is not possible, the datasheet is under NDA :(
> > >
> > > >
> > > > >
> > > > > I think that if the touchscreen would start directly in "application"
> > > > > mode, we could directly use i2c-hid and hid-cypress drivers.
> > > > > Unfortunately, this is not the case.
> > > > >
> > > > > In bootloader mode, the ProductID is 0xc101 and in application mode, it
> > > > > is 0xc001 (already available in hid-ids.h:
> > > > > USB_DEVICE_ID_CYPRESS_TRUETOUCH but not handled)
> > > > >
> > > > > What would be the better approach here?
> > > > > Should I add a new product ID to detect the bootloader mode in
> > > > > hid-cypress driver and send non-HID commands to switch to
> > > > > "application" mode in this driver?
> > > > > Anyway, I guess that I will drop this cyttsp5 driver and update the
> > > > > existing one, right?
> > > >
> > > > So it still accessible through HID, even when in bootloader mode? OK,
> > > > then I guess there are 2 options:
> > > >
> > > > - if device is documented to always start in bootloader mode, you could
> > > > have a small stub driver that switches it into application mode in its
> > > > probe() code. The "bootloader" device will disappear and
> > > > "application" device will appear, and standard driver (hid-multitouch)
> > > > will bind to it.
> > >
> > > Okay, I see. In our case, we do not have the timeout to 0 as after a
> > > moment, the application mode is automatically switched.
> > >
> > > >
> > > > - if device supposed to come up in application mode unless configuration
> > > > is damaged: I'd recommend doing what we do on Chrome OS and have some
> > > > userspace software that runs on boot (or whenever device is
> > > > discovered) and check if it has the latest firmware/configuration, and
> > > > repair device if needed.
> > >
> > > I see.
> > >
> > > I tried to make the i2d-hid & hid-cypress working. This is not
> > > successful for the moment because I can not retrieve the correct
> > > bcdVersion. While debugging, I have noticed that the HID descriptors
> > > don't seem to be exactly the same:
> > >
> > > under i2c-hid.c:
> > >
> > > struct i2c_hid_desc {
> > > __le16 wHIDDescLength;
> > > __le16 bcdVersion;
> > > __le16 wReportDescLength;
> > > __le16 wReportDescRegister;
> > > __le16 wInputRegister;
> > > __le16 wMaxInputLength;
> > > __le16 wOutputRegister;
> > > __le16 wMaxOutputLength;
> > > __le16 wCommandRegister;
> > > __le16 wDataRegister;
> > > __le16 wVendorID;
> > > __le16 wProductID;
> > > __le16 wVersionID;
> > > __le32 reserved;
> > > } __packed;
> > >
> > > whereas in my driver, I have:
> > >
> > > struct cyttsp5_hid_desc {
> > > __le16 hid_desc_len;
> > > u8 packet_id; <-- Different
> > > u8 reserved_byte; <-- Different
> > > __le16 bcd_version;
> > > __le16 report_desc_len;
> > > __le16 report_desc_register;
> > > __le16 input_register;
> > > __le16 max_input_len;
> > > __le16 output_register;
> > > __le16 max_output_len;
> > > __le16 command_register;
> > > __le16 data_register;
> > > __le16 vendor_id;
> > > __le16 product_id;
> > > __le16 version_id;
> > > u8 reserved[4];
> > > } __packed;
> > >
> > > Have you already seen devices that are "HID compatible" with a different
> > > HID descriptor's content like this?
> >
> > That seems like a violation of Microsoft I2C HID protocol:
> > https://docs.microsoft.com/en-us/previous-versions/windows/hardware/design/dn642101(v=vs.85)
> > How do Cypress devices work in Windows? Might they have a compatible
> > firmware?
>
> I do not know how it works on Windows, actually.
> The datasheet indicates that it is based on HID specification. I guess
> it is not "HID compliant" as I was thinking while reading it.
>
> "Packet Interface Protocol (PIP) is a command and response-based
> communication protocol used to communicate with the
> TrueTouch device over the physical communication interface. PIP is
> modeled after Microsoft’s HID over I2C protocol specification, version
> 1.00. However, PIP extends the functionality of HID over I2C protocol
> to support both I2C and SPI physical communication interfaces, raw
> data extraction, self-tests, bootloading, and configuration data
> programming."
>
> >
> > In any case, for all I2C HID things Benjamin (CCed) is your guy.
>
> Okay, thanks.
> I am not so sure it is possible to use HID's drivers, now.
Well, we *could* detect this particular model if the `packet_id` and
the `reserved_byte` fields in place of the `bcd_version` differ from
what we normally expect on a HID descriptor.
I can imagine that we check on the bcd_version, if it's not 0x0100, we
can add a special case for this Cypress device by shifting the
descriptor, making sure we are dealing with this particular device,
and hopefully getting something we can handle now.
Cheers,
Benjamin
^ permalink raw reply
* Re: [PATCH 3/3] Enable high-resolution scrolling on Logitech mice
From: Benjamin Tissoires @ 2018-08-30 7:18 UTC (permalink / raw)
To: hcutts, Nestor Lopez Casado
Cc: open list:HID CORE LAYER, lkml, Dmitry Torokhov, Jiri Kosina
In-Reply-To: <CA+jURcvguwXAVnpQ9+84QQOaJG74oeV8U4zzM1X0UabaY5DJBQ@mail.gmail.com>
Hi Harry,
On Thu, Aug 30, 2018 at 1:06 AM Harry Cutts <hcutts@chromium.org> wrote:
>
> Hi Benjamin,
>
> On Tue, 28 Aug 2018 at 01:47, Benjamin Tissoires
> <benjamin.tissoires@redhat.com> wrote:
> > On Thu, Aug 23, 2018 at 8:31 PM Harry Cutts <hcutts@chromium.org> wrote:
> > > [snip]
> > > @@ -400,32 +409,53 @@ static void hidpp_prefix_name(char **name, int name_length)
> > > #define HIDPP_SET_LONG_REGISTER 0x82
> > > #define HIDPP_GET_LONG_REGISTER 0x83
> > >
> > > -#define HIDPP_REG_GENERAL 0x00
> > > -
> > > -static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev)
> > > +/**
> > > + * 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)
> > > {
> > > 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,
> > > - HIDPP_REG_GENERAL,
> > > - NULL, 0, &response);
> > > + REPORT_ID_HIDPP_SHORT,
> > > + HIDPP_GET_REGISTER,
> > > + register_address,
> > > + NULL, 0, &response);
> > > if (ret)
> > > return ret;
> > >
> > > memcpy(params, response.rap.params, 3);
> > >
> > > - /* Set the battery bit */
> > > - params[0] |= BIT(4);
> > > + params[byte] |= BIT(bit);
> > >
> > > return hidpp_send_rap_command_sync(hidpp_dev,
> > > - REPORT_ID_HIDPP_SHORT,
> > > - HIDPP_SET_REGISTER,
> > > - HIDPP_REG_GENERAL,
> > > - params, 3, &response);
> > > + 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);
> > > +}
> >
> > This hunk should be dealt in a separate patch (including the one function below)
>
> OK, will do in v2.
>
> > > [snip]
> > > @@ -2399,7 +2524,8 @@ 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);
> > > - input_report_rel(mydata->input, REL_WHEEL, v);
> > > + hid_scroll_counter_handle_scroll(
> > > + &hidpp->vertical_wheel_counter, v);
> >
> > The conversion input_report_rel(... REL_WHEEL,...) to
> > hid_scroll_counter_handle_scroll() should be dealt in a separate
> > patch.
>
> OK, I'll do that in v2, but might I ask why? I don't see how this
> particular hunk is special.
I tend to consider that existing code rewrite need to be in their
special commit, especially if the change isn't supposed to change the
behaviour. This is my personal taste in case something goes wrong and
(in this case) a m560 suddenly starts complaining about an issue with
this mouse.
I wouldn't mind too much if you rather keep the
hid_scroll_counter_handle_scroll() introduction to this commit though.
>
> >
> > >
> > > input_sync(mydata->input);
> > > }
> > > @@ -2527,6 +2653,71 @@ 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.
> > > + * @mm256_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 mm256_per_hi_res_unit;
> > > +};
> > > +
> > > +static struct hi_res_scroll_info hi_res_scroll_devices[] = {
> > > + { /* Anywhere MX */
> > > + .product_id = 0x1017, .mm256_per_hi_res_unit = 114 },
> > > + { /* Performance MX */
> > > + .product_id = 0x101a, .mm256_per_hi_res_unit = 104 },
> > > + { /* M560 */
> > > + .product_id = 0x402d, .mm256_per_hi_res_unit = 111 },
> > > + { /* MX Master 2S */
> > > + .product_id = 0x4069, .mm256_per_hi_res_unit = 104 },
> > > + { .product_id = USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_2S_BT,
> > > + .mm256_per_hi_res_unit = 104 },
> > > +};
> > > +
> > > +static int hi_res_scroll_look_up_mm256(__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].mm256_per_hi_res_unit;
> > > + }
> > > + return 104;
> >
> > 104?
>
> This seems like a sensible default value in case we don't have a value
> for this mouse in hi_res_scroll_devices. I'll add a comment explaining
> this in v2.
>
> >
> > > [snip]
> > > +static int hidpp_event(struct hid_device *hdev, struct hid_field *field,
> > > + struct hid_usage *usage, __s32 value)
> > > +{
> > > + 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;
> >
> > You are using usage_table to force the .event function to be called
> > only on the WHEEL events. This is correct, but I have a feeling this
> > will be harder to understand when we are going to extend the .event()
> > function for other events.
> > If you rather keep the cde that way, please add a comment at the
> > beginning of the function stating that we are only called against
> > WHEEL events because of usage_table.
>
> OK, I'll add the comment in v2.
>
> > > [snip]
> > >
> > > +#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,
> > > - USB_VENDOR_ID_LOGITECH, 0x4011),
> > > + LDJ_DEVICE(0x4011),
> > > .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT |
> > > HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS },
> > > { /* wireless touchpad T650 */
> > > - HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
> > > - USB_VENDOR_ID_LOGITECH, 0x4101),
> > > + LDJ_DEVICE(0x4101),
> >
> > The rewrite of the existing supported devices should be in a separate patch too.
>
> OK, will do.
>
> > > [snip]
> > > diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
> > > index 249d49b6b16c..7926c275f258 100644
> > > --- a/drivers/hid/hid-quirks.c
> > > +++ b/drivers/hid/hid-quirks.c
> > > @@ -463,6 +463,17 @@ static const struct hid_device_id hid_have_special_driver[] = {
> > > #endif
> > > #if IS_ENABLED(CONFIG_HID_LOGITECH_HIDPP)
> > > { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_T651) },
> > > + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_M336_337_535_BT1) },
> > > + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_M336_337_535_BT2) },
> > > + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_M720_BT) },
> > > + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2_BT1) },
> > > + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2_BT2) },
> > > + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2_BT3) },
> > > + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2S_BT) },
> > > + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_BT1) },
> > > + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_BT2) },
> > > + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_BT3) },
> > > + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_2S_BT) },
> >
> > Since v4.16, this should not be required anymore. Please drop the hunk
> > if I am correct.
>
> Yes, it seems to work fine without it (at least for the MX Master 2S).
> Unfortunately, while testing this I encountered a bug with high-res
> scrolling over Bluetooth. (It seems that if you turn off the MX Master
> 2S while it's connected over Bluetooth, we don't detect that and
> remove the input device, meaning that when it reconnects the driver
> thinks it's in high-res mode but the mouse is in low-res.) I'm
> investigating, but in the meantime I'll remove the Bluetooth support
> from v2 and add it back in later.
As far as I can see, the MX Master 2S is connected over BLE. Bluez
keeps the uhid node opened (and thus the existing bluetooth HID
device) to be able to reconnect faster.
I would suppose you should get notified in the connect event of a
reconnection, but it doesn't seem to be the case.
Nestor, is there any event emitted by the mouse when it gets
reconnected over BLE or is that a bluez issue?
Cheers,
Benjamin
>
> >
> > Cheers,
> > Benjamin
> >
> > > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL) },
> > > #endif
> > > #if IS_ENABLED(CONFIG_HID_LOGITECH_DJ)
> > > --
> > > 2.18.0.1017.ga543ac7ca45-goog
> > >
>
> Thanks,
>
> Harry Cutts
> Chrome OS Touch/Input team
^ permalink raw reply
* Re: [PATCH v6 0/2] Input: Add Cypress Gen5 Touchscreen driver
From: Mylène Josserand @ 2018-08-30 7:12 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Rob Herring, Mark Rutland, Mylène Josserand,
Thomas Petazzoni, Maxime Ripard, lkml, DTML, Benjamin Tissoires,
linux-input@vger.kernel.org
In-Reply-To: <CAKdAkRQQ27TNmDSSg5x4kGvhhBjRbM9G2Bv_1WBxAhYWNUkz1w@mail.gmail.com>
Hello Dmitry,
On Mon, 13 Aug 2018 08:36:32 -0700
Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> Hi Mylène,
>
> On Mon, Aug 13, 2018 at 8:24 AM Mylène Josserand
> <mylene.josserand@bootlin.com> wrote:
> >
> > Hi Dmitry,
> >
> > On Tue, 24 Jul 2018 10:40:53 -0700
> > Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> >
> > > Hi Mylène,
> > >
> > > On Tue, Jul 24, 2018 at 03:00:46PM +0200, Mylène Josserand wrote:
> > > > Hello Dmitry,
> > > >
> > > > On Wed, 4 Jul 2018 16:21:58 +0000
> > > > Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> > > >
> > > > > Hi Mylène,
> > > > >
> > > > > On Tue, Jul 03, 2018 at 11:43:07AM +0200, Mylène Josserand wrote:
> > > > > > Hello,
> > > > > >
> > > > > > Here is a V6 series to add the driver of the touchscreen Cypress,
> > > > > > TrueTouch Generation 5.
> > > > > > Based on v4.18-rc3.
> > > > > >
> > > > > > This patch series has already been posted in several iterations:
> > > > > > - v1: Sent on 2017/05/29
> > > > > > - v2: Sent on 2017/08/18
> > > > > > - v3: Sent on 2017/09/27
> > > > > > - v4: Sent on 2017/12/01
> > > > > > - v5: Sent on 2017/12/20
> > > > > >
> > > > > > I did not have any comments the last 4 versions.
> > > > > > And no reviews on my v5 during 6 months. Could I have any updates
> > > > > > or feedback on my series to know why it is not merged (to be able to
> > > > > > correct what is wrong)?
> > > > >
> > > > > Sorry, I must have missed the v5, sorry about that.
> > > > >
> > > > > I probably asked this question before, but just to make sure - I see
> > > > > references to HID in the patch - the device is really not HID
> > > > > compatible? Is there any hope it could be made work with i2c-hid +
> > > > > hid-multitouch?
> > > > >
> > > > > Thanks.
> > > > >
> > > >
> > > > I have checked and, for what I have seen, all the HID descriptor stuff
> > > > is HID compliant. We could definitely use i2c-hid and hid-multitouch
> > > > (there is the "hid-cypress" driver that exists also).
> > > >
> > > > The only problem is that this touchscreen has two modes: a bootloader
> > > > mode and an application mode (which is the one where we can send
> > > > HID commands). After a power-on-reset, it is always in "bootloader"
> > > > mode so we need to send some commands (called "bootloader commands") to
> > > > switch to application mode.
> > >
> > > Is this a documented or observed behavior? In my practice devices (I am
> > > talking in general, not about Cypress) that have proper configuration
> > > loaded and that were brought up with appropriate power up sequence and
> > > timings automatically switch to application mode. They only end up in
> > > bootloader mode when proper power up sequence is not respected and they
> > > are unhappy.
> >
> > I have checked and indeed, if everything is correctly performed, the
> > bootloader has a timeout to switch to application mode.
> > The datasheet says that this timeout can be configured and the "0" value
> > means that the bootloader will never automatically switch to application
> > unless a bootloader command is sent.
> >
> > In our case, you were right, after a timeout, the touchscreen is
> > correctly switching to Application mode. Great news!
> >
> > >
> > > > These commands are not HID-compliant as the
> > > > datasheet indicates:
> > > >
> > > > "Bootloader commands are not HID-over-I2C compliant."
> > >
> > > Any chance you could share the datasheet?
> >
> > Sorry, it is not possible, the datasheet is under NDA :(
> >
> > >
> > > >
> > > > I think that if the touchscreen would start directly in "application"
> > > > mode, we could directly use i2c-hid and hid-cypress drivers.
> > > > Unfortunately, this is not the case.
> > > >
> > > > In bootloader mode, the ProductID is 0xc101 and in application mode, it
> > > > is 0xc001 (already available in hid-ids.h:
> > > > USB_DEVICE_ID_CYPRESS_TRUETOUCH but not handled)
> > > >
> > > > What would be the better approach here?
> > > > Should I add a new product ID to detect the bootloader mode in
> > > > hid-cypress driver and send non-HID commands to switch to
> > > > "application" mode in this driver?
> > > > Anyway, I guess that I will drop this cyttsp5 driver and update the
> > > > existing one, right?
> > >
> > > So it still accessible through HID, even when in bootloader mode? OK,
> > > then I guess there are 2 options:
> > >
> > > - if device is documented to always start in bootloader mode, you could
> > > have a small stub driver that switches it into application mode in its
> > > probe() code. The "bootloader" device will disappear and
> > > "application" device will appear, and standard driver (hid-multitouch)
> > > will bind to it.
> >
> > Okay, I see. In our case, we do not have the timeout to 0 as after a
> > moment, the application mode is automatically switched.
> >
> > >
> > > - if device supposed to come up in application mode unless configuration
> > > is damaged: I'd recommend doing what we do on Chrome OS and have some
> > > userspace software that runs on boot (or whenever device is
> > > discovered) and check if it has the latest firmware/configuration, and
> > > repair device if needed.
> >
> > I see.
> >
> > I tried to make the i2d-hid & hid-cypress working. This is not
> > successful for the moment because I can not retrieve the correct
> > bcdVersion. While debugging, I have noticed that the HID descriptors
> > don't seem to be exactly the same:
> >
> > under i2c-hid.c:
> >
> > struct i2c_hid_desc {
> > __le16 wHIDDescLength;
> > __le16 bcdVersion;
> > __le16 wReportDescLength;
> > __le16 wReportDescRegister;
> > __le16 wInputRegister;
> > __le16 wMaxInputLength;
> > __le16 wOutputRegister;
> > __le16 wMaxOutputLength;
> > __le16 wCommandRegister;
> > __le16 wDataRegister;
> > __le16 wVendorID;
> > __le16 wProductID;
> > __le16 wVersionID;
> > __le32 reserved;
> > } __packed;
> >
> > whereas in my driver, I have:
> >
> > struct cyttsp5_hid_desc {
> > __le16 hid_desc_len;
> > u8 packet_id; <-- Different
> > u8 reserved_byte; <-- Different
> > __le16 bcd_version;
> > __le16 report_desc_len;
> > __le16 report_desc_register;
> > __le16 input_register;
> > __le16 max_input_len;
> > __le16 output_register;
> > __le16 max_output_len;
> > __le16 command_register;
> > __le16 data_register;
> > __le16 vendor_id;
> > __le16 product_id;
> > __le16 version_id;
> > u8 reserved[4];
> > } __packed;
> >
> > Have you already seen devices that are "HID compatible" with a different
> > HID descriptor's content like this?
>
> That seems like a violation of Microsoft I2C HID protocol:
> https://docs.microsoft.com/en-us/previous-versions/windows/hardware/design/dn642101(v=vs.85)
> How do Cypress devices work in Windows? Might they have a compatible
> firmware?
I do not know how it works on Windows, actually.
The datasheet indicates that it is based on HID specification. I guess
it is not "HID compliant" as I was thinking while reading it.
"Packet Interface Protocol (PIP) is a command and response-based
communication protocol used to communicate with the
TrueTouch device over the physical communication interface. PIP is
modeled after Microsoft’s HID over I2C protocol specification, version
1.00. However, PIP extends the functionality of HID over I2C protocol
to support both I2C and SPI physical communication interfaces, raw
data extraction, self-tests, bootloading, and configuration data
programming."
>
> In any case, for all I2C HID things Benjamin (CCed) is your guy.
Okay, thanks.
I am not so sure it is possible to use HID's drivers, now.
Best regards,
--
Mylène Josserand, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* [PATCH] HID: core: fix NULL pointer dereference
From: Gustavo A. R. Silva @ 2018-08-29 15:22 UTC (permalink / raw)
To: Stefan Agner, Jiri Kosina, Benjamin Tissoires
Cc: linux-input, linux-kernel, Gustavo A. R. Silva
There is a NULL pointer dereference in case memory resources
for *parse* are not successfully allocated.
Fix this by adding a new goto label and make the execution
path jump to it in case vzalloc() fails.
Addresses-Coverity-ID: 1473081 ("Dereference after null check")
Fixes: b2dd9f2e5a8a ("HID: core: fix memory leak on probe")
Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
---
drivers/hid/hid-core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 4548dae..5bec924 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1000,7 +1000,7 @@ int hid_open_report(struct hid_device *device)
parser = vzalloc(sizeof(struct hid_parser));
if (!parser) {
ret = -ENOMEM;
- goto err;
+ goto alloc_err;
}
parser->device = device;
@@ -1049,6 +1049,7 @@ int hid_open_report(struct hid_device *device)
hid_err(device, "item fetching failed at offset %d\n", (int)(end - start));
err:
kfree(parser->collection_stack);
+alloc_err:
vfree(parser);
hid_close_report(device);
return ret;
--
2.7.4
^ permalink raw reply related
* Re: [PATCH V5 2/3] dt-bindings: input: Add document bindings for DA7280
From: Rob Herring @ 2018-08-28 22:20 UTC (permalink / raw)
To: Roy Im
Cc: Dmitry Torokhov, Rob Herring, Mark Rutland, Support Opensource,
devicetree, linux-input, linux-kernel
In-Reply-To: <a0aba6fe0b63f5a685743c88e192701731e289ab.1535358095.git.Roy.Im@diasemi.com>
On Mon, 27 Aug 2018 17:21:35 +0900, Roy Im wrote:
>
> Add device tree binding information for DA7280 haptic driver.
> Example bindings for DA7280 are added.
>
> Signed-off-by: Roy Im <roy.im.opensource@diasemi.com>
>
> ---
> v5: Updated descriptions and fixed errors.
> v4: Fixed commit message, properties.
> v3: Fixed subject format.
> v2: No changes
>
>
> .../devicetree/bindings/input/dlg,da7280.txt | 105 ++++++++++++++++++++
> 1 file changed, 105 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/input/dlg,da7280.txt
>
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* Re: [PATCH] [v2] HID: add support for Apple Magic Trackpad 2
From: Henrik Rydberg @ 2018-08-28 20:56 UTC (permalink / raw)
To: Sean O'Brien
Cc: Benjamin Tissoires, Marek Wyborski, linux-kernel, Dmitry Torokhov,
linux-input, Jiri Kosina, Claudio Mettler
In-Reply-To: <20180828161616.93825-1-seobrien@chromium.org>
Hi Sean,
Thanks for the driver. Looking good, but I do have some comments below.
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index 79bdf0c7e351..d6d0b20cc015 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -88,9 +88,11 @@
> #define USB_DEVICE_ID_ANTON_TOUCH_PAD 0x3101
>
> #define USB_VENDOR_ID_APPLE 0x05ac
> +#define BT_VENDOR_ID_APPLE 0x004c
> #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
> #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
> #define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e
> +#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 0x0265
> #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e
> #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f
> #define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214
> diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
> index b454c4386157..7f14866ea3c7 100644
> --- a/drivers/hid/hid-magicmouse.c
> +++ b/drivers/hid/hid-magicmouse.c
> @@ -54,6 +54,8 @@ module_param(report_undeciphered, bool, 0644);
> MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event");
>
> #define TRACKPAD_REPORT_ID 0x28
> +#define TRACKPAD2_USB_REPORT_ID 0x02
> +#define TRACKPAD2_BT_REPORT_ID 0x31
> #define MOUSE_REPORT_ID 0x29
> #define DOUBLE_REPORT_ID 0xf7
> /* These definitions are not precise, but they're close enough. (Bits
> @@ -91,6 +93,19 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
> #define TRACKPAD_RES_Y \
> ((TRACKPAD_MAX_Y - TRACKPAD_MIN_Y) / (TRACKPAD_DIMENSION_Y / 100))
>
> +#define TRACKPAD2_DIMENSION_X (float)16000
> +#define TRACKPAD2_MIN_X -3678
> +#define TRACKPAD2_MAX_X 3934
> +#define TRACKPAD2_RES_X \
> + ((TRACKPAD2_MAX_X - TRACKPAD2_MIN_X) / (TRACKPAD2_DIMENSION_X / 100))
> +#define TRACKPAD2_DIMENSION_Y (float)11490
> +#define TRACKPAD2_MIN_Y -2478
> +#define TRACKPAD2_MAX_Y 2587
> +#define TRACKPAD2_RES_Y \
> + ((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100))
> +
> +#define MAX_TOUCHES 16
> +
> /**
> * struct magicmouse_sc - Tracks Magic Mouse-specific data.
> * @input: Input device through which we report events.
> @@ -115,8 +130,8 @@ struct magicmouse_sc {
> short scroll_x;
> short scroll_y;
> u8 size;
> - } touches[16];
> - int tracking_ids[16];
> + } touches[MAX_TOUCHES];
> + int tracking_ids[MAX_TOUCHES];
> };
>
> static int magicmouse_firm_touch(struct magicmouse_sc *msc)
> @@ -183,6 +198,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
> {
> struct input_dev *input = msc->input;
> int id, x, y, size, orientation, touch_major, touch_minor, state, down;
> + int pressure = 0;
>
> if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
> id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf;
> @@ -194,7 +210,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
> touch_minor = tdata[4];
> state = tdata[7] & TOUCH_STATE_MASK;
> down = state != TOUCH_STATE_NONE;
> - } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
> + } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD) {
> id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf;
> x = (tdata[1] << 27 | tdata[0] << 19) >> 19;
> y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19);
> @@ -204,6 +220,18 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
> touch_minor = tdata[5];
> state = tdata[8] & TOUCH_STATE_MASK;
> down = state != TOUCH_STATE_NONE;
> + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 */
The else clause is ill-suited for your specific addition, since any
odd device out there if they existed, would suddenly be treated as
something different. Better reverse the logic here.
> + id = tdata[8] & 0xf;
> + x = (tdata[1] << 27 | tdata[0] << 19) >> 19;
> + y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19);
> + size = tdata[6];
> + orientation = (tdata[8] >> 5) - 4;
> + touch_major = tdata[4];
> + touch_minor = tdata[5];
> + /* Prevent zero and low pressure values */
> + pressure = tdata[7] + 30;
Same question as Benjamin: what does + 30 stand for here?
> + state = tdata[3] & 0xC0;
> + down = state == 0x80;
> }
>
> /* Store tracking ID and other fields. */
> @@ -215,7 +243,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
> /* If requested, emulate a scroll wheel by detecting small
> * vertical touch motions.
> */
> - if (emulate_scroll_wheel) {
> + if (emulate_scroll_wheel &&
> + (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE)) {
Similar problem here; how do you know only the magicmouse is the
complete complement of trackpad2? Better use != trackpad2 here.
> unsigned long now = jiffies;
> int step_x = msc->touches[id].scroll_x - x;
> int step_y = msc->touches[id].scroll_y - y;
> @@ -258,7 +287,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
> if (down)
> msc->ntouches++;
>
> - input_mt_slot(input, id);
> + input_mt_slot(input, input_mt_get_slot_by_key(input, id));
Sure you want to change this behavior for all models? I would think no.
> input_mt_report_slot_state(input, MT_TOOL_FINGER, down);
>
> /* Generate the input events for this touch. */
> @@ -269,10 +298,14 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
> input_report_abs(input, ABS_MT_POSITION_X, x);
> input_report_abs(input, ABS_MT_POSITION_Y, y);
>
> + if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2)
> + input_report_abs(input, ABS_MT_PRESSURE, pressure);
> +
> if (report_undeciphered) {
> if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
> input_event(input, EV_MSC, MSC_RAW, tdata[7]);
> - else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
> + else if (input->id.product ==
> + USB_DEVICE_ID_APPLE_MAGICTRACKPAD)
> input_event(input, EV_MSC, MSC_RAW, tdata[8]);
> }
> }
> @@ -283,14 +316,23 @@ static int magicmouse_raw_event(struct hid_device *hdev,
> {
> struct magicmouse_sc *msc = hid_get_drvdata(hdev);
> struct input_dev *input = msc->input;
> - int x = 0, y = 0, ii, clicks = 0, npoints;
> + int x = 0, y = 0, ii, clicks = 0, npoints, prefix_size;
>
> switch (data[0]) {
> case TRACKPAD_REPORT_ID:
> - /* Expect four bytes of prefix, and N*9 bytes of touch data. */
> - if (size < 4 || ((size - 4) % 9) != 0)
> + case TRACKPAD2_BT_REPORT_ID:
> + case TRACKPAD2_USB_REPORT_ID:
> + /* Expect four or twelve bytes of prefix, and N*9 bytes of
> + * touch data.
> + */
> + if (data[0] == TRACKPAD_REPORT_ID ||
> + data[0] == TRACKPAD2_BT_REPORT_ID)
> + prefix_size = 4;
> + else /*TRACKPAD2_USB_REPORT_ID*/
> + prefix_size = 12;
With so little code to actually reproduce in the switch statement, why
not use the switch statement instead? Also the simplest way to ensure
that no code path is unaltered unintentionally.
> + if (size < prefix_size || ((size - prefix_size) % 9) != 0)
> return 0;
> - npoints = (size - 4) / 9;
> + npoints = (size - prefix_size) / 9;
> if (npoints > 15) {
> hid_warn(hdev, "invalid size value (%d) for TRACKPAD_REPORT_ID\n",
> size);
> @@ -298,15 +340,10 @@ static int magicmouse_raw_event(struct hid_device *hdev,
> }
> msc->ntouches = 0;
> for (ii = 0; ii < npoints; ii++)
> - magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
> + magicmouse_emit_touch(msc, ii,
> + data + ii * 9 + prefix_size);
>
> clicks = data[1];
> -
> - /* The following bits provide a device specific timestamp. They
> - * are unused here.
> - *
> - * ts = data[1] >> 6 | data[2] << 2 | data[3] << 10;
> - */
> break;
> case MOUSE_REPORT_ID:
> /* Expect six bytes of prefix, and N*8 bytes of touch data. */
> @@ -352,9 +389,12 @@ static int magicmouse_raw_event(struct hid_device *hdev,
> magicmouse_emit_buttons(msc, clicks & 3);
> input_report_rel(input, REL_X, x);
> input_report_rel(input, REL_Y, y);
> - } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
> + } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD) {
> input_report_key(input, BTN_MOUSE, clicks & 1);
> input_mt_report_pointer_emulation(input, true);
> + } else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 */ {
> + input_mt_sync_frame(input);
> + input_report_key(input, BTN_MOUSE, clicks & 1);
> }
Again, the use of the else clause is a bit backwards - better insert the special case in case the else clause would happen to cover more than one device.
>
> input_sync(input);
> @@ -364,6 +404,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
> static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev)
> {
> int error;
> + int mt_flags = 0;
>
> __set_bit(EV_KEY, input->evbit);
>
> @@ -380,7 +421,7 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
> __set_bit(REL_WHEEL, input->relbit);
> __set_bit(REL_HWHEEL, input->relbit);
> }
> - } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
> + } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD) {
> /* input->keybit is initialized with incorrect button info
> * for Magic Trackpad. There really is only one physical
> * button (BTN_LEFT == BTN_MOUSE). Make sure we don't
> @@ -397,19 +438,35 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
> __set_bit(BTN_TOUCH, input->keybit);
> __set_bit(INPUT_PROP_POINTER, input->propbit);
> __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
> + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) */
Same here.
> +
> + /* setting the device name to ensure the same driver settings
> + * get loaded, whether connected through bluetooth or USB
> + */
> + input->name = "Apple Inc. Magic Trackpad 2";
> +
> + __clear_bit(EV_MSC, input->evbit);
> + __clear_bit(BTN_0, input->keybit);
> + __clear_bit(BTN_RIGHT, input->keybit);
> + __clear_bit(BTN_MIDDLE, input->keybit);
> + __set_bit(BTN_MOUSE, input->keybit);
> + __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
> + __set_bit(BTN_TOOL_FINGER, input->keybit);
> +
> + mt_flags = INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED |
> + INPUT_MT_TRACK;
> }
>
>
> __set_bit(EV_ABS, input->evbit);
>
> - error = input_mt_init_slots(input, 16, 0);
> + error = input_mt_init_slots(input, MAX_TOUCHES, mt_flags);
> if (error)
> return error;
> input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2,
> 4, 0);
> input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2,
> 4, 0);
> - input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
>
> /* Note: Touch Y position from the device is inverted relative
> * to how pointer motion is reported (and relative to how USB
> @@ -418,6 +475,7 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
> * inverse of the reported Y.
> */
> if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
> + input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
> input_set_abs_params(input, ABS_MT_POSITION_X,
> MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
> input_set_abs_params(input, ABS_MT_POSITION_Y,
> @@ -427,7 +485,8 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
> MOUSE_RES_X);
> input_abs_set_res(input, ABS_MT_POSITION_Y,
> MOUSE_RES_Y);
> - } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
> + } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD) {
> + input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
> input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X,
> TRACKPAD_MAX_X, 4, 0);
> input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y,
> @@ -443,11 +502,29 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
> TRACKPAD_RES_X);
> input_abs_set_res(input, ABS_MT_POSITION_Y,
> TRACKPAD_RES_Y);
> + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 */
Same here.
> + input_set_abs_params(input, ABS_MT_PRESSURE, 0, 283, 0, 0);
> + input_set_abs_params(input, ABS_PRESSURE, 0, 283, 0, 0);
> + input_set_abs_params(input, ABS_MT_ORIENTATION, -3, 4, 0, 0);
> + input_set_abs_params(input, ABS_X, TRACKPAD2_MIN_X,
> + TRACKPAD2_MAX_X, 0, 0);
> + input_set_abs_params(input, ABS_Y, TRACKPAD2_MIN_Y,
> + TRACKPAD2_MAX_Y, 0, 0);
> + input_set_abs_params(input, ABS_MT_POSITION_X,
> + TRACKPAD2_MIN_X, TRACKPAD2_MAX_X, 0, 0);
> + input_set_abs_params(input, ABS_MT_POSITION_Y,
> + TRACKPAD2_MIN_Y, TRACKPAD2_MAX_Y, 0, 0);
> +
> + input_abs_set_res(input, ABS_X, TRACKPAD2_RES_X);
> + input_abs_set_res(input, ABS_Y, TRACKPAD2_RES_Y);
> + input_abs_set_res(input, ABS_MT_POSITION_X, TRACKPAD2_RES_X);
> + input_abs_set_res(input, ABS_MT_POSITION_Y, TRACKPAD2_RES_Y);
> }
>
> input_set_events_per_packet(input, 60);
>
> - if (report_undeciphered) {
> + if (report_undeciphered &&
> + input->id.product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
> __set_bit(EV_MSC, input->evbit);
> __set_bit(MSC_RAW, input->mscbit);
> }
> @@ -465,7 +542,8 @@ static int magicmouse_input_mapping(struct hid_device *hdev,
> msc->input = hi->input;
>
> /* Magic Trackpad does not give relative data after switching to MT */
> - if (hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD &&
> + if ((hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD ||
> + hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) &&
> field->flags & HID_MAIN_ITEM_RELATIVE)
> return -1;
>
> @@ -494,11 +572,19 @@ static int magicmouse_input_configured(struct hid_device *hdev,
> static int magicmouse_probe(struct hid_device *hdev,
> const struct hid_device_id *id)
> {
> - const u8 feature[] = { 0xd7, 0x01 };
> - u8 *buf;
> + __u8 feature_mt[] = { 0xD7, 0x01 };
> + __u8 feature_mt_trackpad2_usb[] = { 0x02, 0x01 };
> + __u8 feature_mt_trackpad2_bt[] = { 0xF1, 0x02, 0x01 };
> + __u8 *feature;
If you kept buf here, setting feature before the kmemdup(), you would not need to change so much code.
> struct magicmouse_sc *msc;
> struct hid_report *report;
> int ret;
> + int feature_size;
> +
> + if (id->vendor == USB_VENDOR_ID_APPLE &&
> + id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
> + hdev->type != HID_TYPE_USBMOUSE)
> + return 0;
>
> msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL);
> if (msc == NULL) {
> @@ -532,11 +618,18 @@ static int magicmouse_probe(struct hid_device *hdev,
> if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
> report = hid_register_report(hdev, HID_INPUT_REPORT,
> MOUSE_REPORT_ID, 0);
> - else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
> + else if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD) {
> report = hid_register_report(hdev, HID_INPUT_REPORT,
> TRACKPAD_REPORT_ID, 0);
> report = hid_register_report(hdev, HID_INPUT_REPORT,
> DOUBLE_REPORT_ID, 0);
> + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 */
And here.
> + if (id->vendor == BT_VENDOR_ID_APPLE)
> + report = hid_register_report(hdev, HID_INPUT_REPORT,
> + TRACKPAD2_BT_REPORT_ID, 0);
> + else /* USB_VENDOR_ID_APPLE */
> + report = hid_register_report(hdev, HID_INPUT_REPORT,
> + TRACKPAD2_USB_REPORT_ID, 0);
> }
>
> if (!report) {
> @@ -546,12 +639,6 @@ static int magicmouse_probe(struct hid_device *hdev,
> }
> report->size = 6;
>
> - buf = kmemdup(feature, sizeof(feature), GFP_KERNEL);
> - if (!buf) {
> - ret = -ENOMEM;
> - goto err_stop_hw;
> - }
> -
> /*
> * Some devices repond with 'invalid report id' when feature
> * report switching it into multitouch mode is sent to it.
> @@ -560,10 +647,29 @@ static int magicmouse_probe(struct hid_device *hdev,
> * but there seems to be no other way of switching the mode.
> * Thus the super-ugly hacky success check below.
> */
> - ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(feature),
> - HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
> - kfree(buf);
> - if (ret != -EIO && ret != sizeof(feature)) {
> + if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE ||
> + id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD) {
> + feature_size = sizeof(feature_mt);
> + feature = kmemdup(feature_mt, feature_size, GFP_KERNEL);
> + } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 */
The else thing.
> + if (id->vendor == BT_VENDOR_ID_APPLE) {
> + feature_size = sizeof(feature_mt_trackpad2_bt);
> + feature = kmemdup(feature_mt_trackpad2_bt,
> + feature_size, GFP_KERNEL);
> + } else { /* USB_VENDOR_ID_APPLE */
> + feature_size = sizeof(feature_mt_trackpad2_usb);
> + feature = kmemdup(feature_mt_trackpad2_usb,
> + feature_size, GFP_KERNEL);
> + }
> + }
> + if (!feature) {
> + ret = -ENOMEM;
> + goto err_stop_hw;
> + }
> + ret = hid_hw_raw_request(hdev, feature[0], feature, feature_size,
> + HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
> + kfree(feature);
> + if (ret != -EIO && ret != feature_size) {
> hid_err(hdev, "unable to request touch data (%d)\n", ret);
> goto err_stop_hw;
> }
> @@ -579,6 +685,10 @@ static const struct hid_device_id magic_mice[] = {
> USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 },
> { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
> USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 },
> + { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE,
> + USB_DEVICE_ID_APPLE_MAGICTRACKPAD2), .driver_data = 0 },
> + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
> + USB_DEVICE_ID_APPLE_MAGICTRACKPAD2), .driver_data = 0 },
> { }
> };
> MODULE_DEVICE_TABLE(hid, magic_mice);
> --
> 2.19.0.rc0.228.g281dcd1b4d0-goog
>
Thanks!
Henrik
^ permalink raw reply
* Re: [PATCH 1/3] Add the `REL_WHEEL_HI_RES` event code
From: Harry Cutts @ 2018-08-28 17:49 UTC (permalink / raw)
To: jikos
Cc: dmitry.torokhov, willy, linux-input, linux-kernel, jiri.kosina,
benjamin.tissoires, linux-doc, corbet
In-Reply-To: <nycvar.YFH.7.76.1808281101500.25787@cbobk.fhfr.pm>
Benjamin says he prefers micrometres, and I think I do to now that I
think about it (sticking with SI seems like a good idea), so I'll
update it in a V2.
Harry Cutts
Chrome OS Touch/Input team
Harry Cutts
Chrome OS Touch/Input team
On Tue, 28 Aug 2018 at 02:02, Jiri Kosina <jikos@kernel.org> wrote:
>
> On Thu, 23 Aug 2018, Dmitry Torokhov wrote:
>
> > > > + - 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 256ths of a millimeter.
> > >
> > > Is it too late to change this to an actual unit like micrometres?
> >
> > No love for imperial roots? Sure, micrometers would work too I think.
>
> I don't really care strongly :) Is either of you going to update the
> patch? Otherwise I'll just apply as-is.
>
> Thanks,
>
> --
> Jiri Kosina
> SUSE Labs
>
^ permalink raw reply
* [PATCH] [v2] HID: add support for Apple Magic Trackpad 2
From: Sean O'Brien @ 2018-08-28 16:16 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Sean O'Brien, Marek Wyborski, linux-kernel, Dmitry Torokhov,
linux-input, Henrik Rydberg, Jiri Kosina, Claudio Mettler
USB device
Vendor 05ac (Apple)
Device 0265 (Magic Trackpad 2)
Bluetooth device
Vendor 004c (Apple)
Device 0265 (Magic Trackpad 2)
Add support for Apple Magic Trackpad 2 over USB and bluetooth, putting
the device in multi-touch mode.
Signed-off-by: Claudio Mettler <claudio@ponyfleisch.ch>
Signed-off-by: Marek Wyborski <marek.wyborski@emwesoft.com>
Signed-off-by: Sean O'Brien <seobrien@chromium.org>
---
drivers/hid/hid-ids.h | 2 +
drivers/hid/hid-magicmouse.c | 184 ++++++++++++++++++++++++++++-------
2 files changed, 149 insertions(+), 37 deletions(-)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 79bdf0c7e351..d6d0b20cc015 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -88,9 +88,11 @@
#define USB_DEVICE_ID_ANTON_TOUCH_PAD 0x3101
#define USB_VENDOR_ID_APPLE 0x05ac
+#define BT_VENDOR_ID_APPLE 0x004c
#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e
+#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 0x0265
#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e
#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f
#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index b454c4386157..7f14866ea3c7 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -54,6 +54,8 @@ module_param(report_undeciphered, bool, 0644);
MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event");
#define TRACKPAD_REPORT_ID 0x28
+#define TRACKPAD2_USB_REPORT_ID 0x02
+#define TRACKPAD2_BT_REPORT_ID 0x31
#define MOUSE_REPORT_ID 0x29
#define DOUBLE_REPORT_ID 0xf7
/* These definitions are not precise, but they're close enough. (Bits
@@ -91,6 +93,19 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
#define TRACKPAD_RES_Y \
((TRACKPAD_MAX_Y - TRACKPAD_MIN_Y) / (TRACKPAD_DIMENSION_Y / 100))
+#define TRACKPAD2_DIMENSION_X (float)16000
+#define TRACKPAD2_MIN_X -3678
+#define TRACKPAD2_MAX_X 3934
+#define TRACKPAD2_RES_X \
+ ((TRACKPAD2_MAX_X - TRACKPAD2_MIN_X) / (TRACKPAD2_DIMENSION_X / 100))
+#define TRACKPAD2_DIMENSION_Y (float)11490
+#define TRACKPAD2_MIN_Y -2478
+#define TRACKPAD2_MAX_Y 2587
+#define TRACKPAD2_RES_Y \
+ ((TRACKPAD2_MAX_Y - TRACKPAD2_MIN_Y) / (TRACKPAD2_DIMENSION_Y / 100))
+
+#define MAX_TOUCHES 16
+
/**
* struct magicmouse_sc - Tracks Magic Mouse-specific data.
* @input: Input device through which we report events.
@@ -115,8 +130,8 @@ struct magicmouse_sc {
short scroll_x;
short scroll_y;
u8 size;
- } touches[16];
- int tracking_ids[16];
+ } touches[MAX_TOUCHES];
+ int tracking_ids[MAX_TOUCHES];
};
static int magicmouse_firm_touch(struct magicmouse_sc *msc)
@@ -183,6 +198,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
{
struct input_dev *input = msc->input;
int id, x, y, size, orientation, touch_major, touch_minor, state, down;
+ int pressure = 0;
if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf;
@@ -194,7 +210,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
touch_minor = tdata[4];
state = tdata[7] & TOUCH_STATE_MASK;
down = state != TOUCH_STATE_NONE;
- } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+ } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD) {
id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf;
x = (tdata[1] << 27 | tdata[0] << 19) >> 19;
y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19);
@@ -204,6 +220,18 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
touch_minor = tdata[5];
state = tdata[8] & TOUCH_STATE_MASK;
down = state != TOUCH_STATE_NONE;
+ } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 */
+ id = tdata[8] & 0xf;
+ x = (tdata[1] << 27 | tdata[0] << 19) >> 19;
+ y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19);
+ size = tdata[6];
+ orientation = (tdata[8] >> 5) - 4;
+ touch_major = tdata[4];
+ touch_minor = tdata[5];
+ /* Prevent zero and low pressure values */
+ pressure = tdata[7] + 30;
+ state = tdata[3] & 0xC0;
+ down = state == 0x80;
}
/* Store tracking ID and other fields. */
@@ -215,7 +243,8 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
/* If requested, emulate a scroll wheel by detecting small
* vertical touch motions.
*/
- if (emulate_scroll_wheel) {
+ if (emulate_scroll_wheel &&
+ (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE)) {
unsigned long now = jiffies;
int step_x = msc->touches[id].scroll_x - x;
int step_y = msc->touches[id].scroll_y - y;
@@ -258,7 +287,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
if (down)
msc->ntouches++;
- input_mt_slot(input, id);
+ input_mt_slot(input, input_mt_get_slot_by_key(input, id));
input_mt_report_slot_state(input, MT_TOOL_FINGER, down);
/* Generate the input events for this touch. */
@@ -269,10 +298,14 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
input_report_abs(input, ABS_MT_POSITION_X, x);
input_report_abs(input, ABS_MT_POSITION_Y, y);
+ if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2)
+ input_report_abs(input, ABS_MT_PRESSURE, pressure);
+
if (report_undeciphered) {
if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
input_event(input, EV_MSC, MSC_RAW, tdata[7]);
- else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+ else if (input->id.product ==
+ USB_DEVICE_ID_APPLE_MAGICTRACKPAD)
input_event(input, EV_MSC, MSC_RAW, tdata[8]);
}
}
@@ -283,14 +316,23 @@ static int magicmouse_raw_event(struct hid_device *hdev,
{
struct magicmouse_sc *msc = hid_get_drvdata(hdev);
struct input_dev *input = msc->input;
- int x = 0, y = 0, ii, clicks = 0, npoints;
+ int x = 0, y = 0, ii, clicks = 0, npoints, prefix_size;
switch (data[0]) {
case TRACKPAD_REPORT_ID:
- /* Expect four bytes of prefix, and N*9 bytes of touch data. */
- if (size < 4 || ((size - 4) % 9) != 0)
+ case TRACKPAD2_BT_REPORT_ID:
+ case TRACKPAD2_USB_REPORT_ID:
+ /* Expect four or twelve bytes of prefix, and N*9 bytes of
+ * touch data.
+ */
+ if (data[0] == TRACKPAD_REPORT_ID ||
+ data[0] == TRACKPAD2_BT_REPORT_ID)
+ prefix_size = 4;
+ else /*TRACKPAD2_USB_REPORT_ID*/
+ prefix_size = 12;
+ if (size < prefix_size || ((size - prefix_size) % 9) != 0)
return 0;
- npoints = (size - 4) / 9;
+ npoints = (size - prefix_size) / 9;
if (npoints > 15) {
hid_warn(hdev, "invalid size value (%d) for TRACKPAD_REPORT_ID\n",
size);
@@ -298,15 +340,10 @@ static int magicmouse_raw_event(struct hid_device *hdev,
}
msc->ntouches = 0;
for (ii = 0; ii < npoints; ii++)
- magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
+ magicmouse_emit_touch(msc, ii,
+ data + ii * 9 + prefix_size);
clicks = data[1];
-
- /* The following bits provide a device specific timestamp. They
- * are unused here.
- *
- * ts = data[1] >> 6 | data[2] << 2 | data[3] << 10;
- */
break;
case MOUSE_REPORT_ID:
/* Expect six bytes of prefix, and N*8 bytes of touch data. */
@@ -352,9 +389,12 @@ static int magicmouse_raw_event(struct hid_device *hdev,
magicmouse_emit_buttons(msc, clicks & 3);
input_report_rel(input, REL_X, x);
input_report_rel(input, REL_Y, y);
- } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+ } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD) {
input_report_key(input, BTN_MOUSE, clicks & 1);
input_mt_report_pointer_emulation(input, true);
+ } else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 */ {
+ input_mt_sync_frame(input);
+ input_report_key(input, BTN_MOUSE, clicks & 1);
}
input_sync(input);
@@ -364,6 +404,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev)
{
int error;
+ int mt_flags = 0;
__set_bit(EV_KEY, input->evbit);
@@ -380,7 +421,7 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
__set_bit(REL_WHEEL, input->relbit);
__set_bit(REL_HWHEEL, input->relbit);
}
- } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+ } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD) {
/* input->keybit is initialized with incorrect button info
* for Magic Trackpad. There really is only one physical
* button (BTN_LEFT == BTN_MOUSE). Make sure we don't
@@ -397,19 +438,35 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
__set_bit(BTN_TOUCH, input->keybit);
__set_bit(INPUT_PROP_POINTER, input->propbit);
__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
+ } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) */
+
+ /* setting the device name to ensure the same driver settings
+ * get loaded, whether connected through bluetooth or USB
+ */
+ input->name = "Apple Inc. Magic Trackpad 2";
+
+ __clear_bit(EV_MSC, input->evbit);
+ __clear_bit(BTN_0, input->keybit);
+ __clear_bit(BTN_RIGHT, input->keybit);
+ __clear_bit(BTN_MIDDLE, input->keybit);
+ __set_bit(BTN_MOUSE, input->keybit);
+ __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
+ __set_bit(BTN_TOOL_FINGER, input->keybit);
+
+ mt_flags = INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED |
+ INPUT_MT_TRACK;
}
__set_bit(EV_ABS, input->evbit);
- error = input_mt_init_slots(input, 16, 0);
+ error = input_mt_init_slots(input, MAX_TOUCHES, mt_flags);
if (error)
return error;
input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2,
4, 0);
input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2,
4, 0);
- input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
/* Note: Touch Y position from the device is inverted relative
* to how pointer motion is reported (and relative to how USB
@@ -418,6 +475,7 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
* inverse of the reported Y.
*/
if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
+ input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
input_set_abs_params(input, ABS_MT_POSITION_X,
MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
input_set_abs_params(input, ABS_MT_POSITION_Y,
@@ -427,7 +485,8 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
MOUSE_RES_X);
input_abs_set_res(input, ABS_MT_POSITION_Y,
MOUSE_RES_Y);
- } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+ } else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD) {
+ input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X,
TRACKPAD_MAX_X, 4, 0);
input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y,
@@ -443,11 +502,29 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
TRACKPAD_RES_X);
input_abs_set_res(input, ABS_MT_POSITION_Y,
TRACKPAD_RES_Y);
+ } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 */
+ input_set_abs_params(input, ABS_MT_PRESSURE, 0, 283, 0, 0);
+ input_set_abs_params(input, ABS_PRESSURE, 0, 283, 0, 0);
+ input_set_abs_params(input, ABS_MT_ORIENTATION, -3, 4, 0, 0);
+ input_set_abs_params(input, ABS_X, TRACKPAD2_MIN_X,
+ TRACKPAD2_MAX_X, 0, 0);
+ input_set_abs_params(input, ABS_Y, TRACKPAD2_MIN_Y,
+ TRACKPAD2_MAX_Y, 0, 0);
+ input_set_abs_params(input, ABS_MT_POSITION_X,
+ TRACKPAD2_MIN_X, TRACKPAD2_MAX_X, 0, 0);
+ input_set_abs_params(input, ABS_MT_POSITION_Y,
+ TRACKPAD2_MIN_Y, TRACKPAD2_MAX_Y, 0, 0);
+
+ input_abs_set_res(input, ABS_X, TRACKPAD2_RES_X);
+ input_abs_set_res(input, ABS_Y, TRACKPAD2_RES_Y);
+ input_abs_set_res(input, ABS_MT_POSITION_X, TRACKPAD2_RES_X);
+ input_abs_set_res(input, ABS_MT_POSITION_Y, TRACKPAD2_RES_Y);
}
input_set_events_per_packet(input, 60);
- if (report_undeciphered) {
+ if (report_undeciphered &&
+ input->id.product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
__set_bit(EV_MSC, input->evbit);
__set_bit(MSC_RAW, input->mscbit);
}
@@ -465,7 +542,8 @@ static int magicmouse_input_mapping(struct hid_device *hdev,
msc->input = hi->input;
/* Magic Trackpad does not give relative data after switching to MT */
- if (hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD &&
+ if ((hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD ||
+ hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) &&
field->flags & HID_MAIN_ITEM_RELATIVE)
return -1;
@@ -494,11 +572,19 @@ static int magicmouse_input_configured(struct hid_device *hdev,
static int magicmouse_probe(struct hid_device *hdev,
const struct hid_device_id *id)
{
- const u8 feature[] = { 0xd7, 0x01 };
- u8 *buf;
+ __u8 feature_mt[] = { 0xD7, 0x01 };
+ __u8 feature_mt_trackpad2_usb[] = { 0x02, 0x01 };
+ __u8 feature_mt_trackpad2_bt[] = { 0xF1, 0x02, 0x01 };
+ __u8 *feature;
struct magicmouse_sc *msc;
struct hid_report *report;
int ret;
+ int feature_size;
+
+ if (id->vendor == USB_VENDOR_ID_APPLE &&
+ id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
+ hdev->type != HID_TYPE_USBMOUSE)
+ return 0;
msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL);
if (msc == NULL) {
@@ -532,11 +618,18 @@ static int magicmouse_probe(struct hid_device *hdev,
if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
report = hid_register_report(hdev, HID_INPUT_REPORT,
MOUSE_REPORT_ID, 0);
- else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
+ else if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD) {
report = hid_register_report(hdev, HID_INPUT_REPORT,
TRACKPAD_REPORT_ID, 0);
report = hid_register_report(hdev, HID_INPUT_REPORT,
DOUBLE_REPORT_ID, 0);
+ } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 */
+ if (id->vendor == BT_VENDOR_ID_APPLE)
+ report = hid_register_report(hdev, HID_INPUT_REPORT,
+ TRACKPAD2_BT_REPORT_ID, 0);
+ else /* USB_VENDOR_ID_APPLE */
+ report = hid_register_report(hdev, HID_INPUT_REPORT,
+ TRACKPAD2_USB_REPORT_ID, 0);
}
if (!report) {
@@ -546,12 +639,6 @@ static int magicmouse_probe(struct hid_device *hdev,
}
report->size = 6;
- buf = kmemdup(feature, sizeof(feature), GFP_KERNEL);
- if (!buf) {
- ret = -ENOMEM;
- goto err_stop_hw;
- }
-
/*
* Some devices repond with 'invalid report id' when feature
* report switching it into multitouch mode is sent to it.
@@ -560,10 +647,29 @@ static int magicmouse_probe(struct hid_device *hdev,
* but there seems to be no other way of switching the mode.
* Thus the super-ugly hacky success check below.
*/
- ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(feature),
- HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
- kfree(buf);
- if (ret != -EIO && ret != sizeof(feature)) {
+ if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE ||
+ id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD) {
+ feature_size = sizeof(feature_mt);
+ feature = kmemdup(feature_mt, feature_size, GFP_KERNEL);
+ } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 */
+ if (id->vendor == BT_VENDOR_ID_APPLE) {
+ feature_size = sizeof(feature_mt_trackpad2_bt);
+ feature = kmemdup(feature_mt_trackpad2_bt,
+ feature_size, GFP_KERNEL);
+ } else { /* USB_VENDOR_ID_APPLE */
+ feature_size = sizeof(feature_mt_trackpad2_usb);
+ feature = kmemdup(feature_mt_trackpad2_usb,
+ feature_size, GFP_KERNEL);
+ }
+ }
+ if (!feature) {
+ ret = -ENOMEM;
+ goto err_stop_hw;
+ }
+ ret = hid_hw_raw_request(hdev, feature[0], feature, feature_size,
+ HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
+ kfree(feature);
+ if (ret != -EIO && ret != feature_size) {
hid_err(hdev, "unable to request touch data (%d)\n", ret);
goto err_stop_hw;
}
@@ -579,6 +685,10 @@ static const struct hid_device_id magic_mice[] = {
USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 },
+ { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_MAGICTRACKPAD2), .driver_data = 0 },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_MAGICTRACKPAD2), .driver_data = 0 },
{ }
};
MODULE_DEVICE_TABLE(hid, magic_mice);
--
2.19.0.rc0.228.g281dcd1b4d0-goog
^ permalink raw reply related
* Re: [PATCH] input: olpc_apsp: remove unused pointer 'np'
From: Andi Shyti @ 2018-08-28 15:14 UTC (permalink / raw)
To: Colin King; +Cc: Dmitry Torokhov, linux-input, kernel-janitors, linux-kernel
In-Reply-To: <20180828145648.11619-1-colin.king@canonical.com>
Hi Colin,
On Tue, Aug 28, 2018 at 03:56:48PM +0100, Colin King wrote:
> From: Colin Ian King <colin.king@canonical.com>
>
> Pointer 'nb' is being assigned but is never used hence it is
'np' here. Other than that,
Reviewed-by: Andi Shyti <andi@etezian.org>
Andi
> redundant and can be removed.
>
> Cleans up clang warning:
> warning: variable 'np' set but not used [-Wunused-but-set-variable]
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> ---
> drivers/input/serio/olpc_apsp.c | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/drivers/input/serio/olpc_apsp.c b/drivers/input/serio/olpc_apsp.c
> index 8e9a4209fcad..8bd8ed25946f 100644
> --- a/drivers/input/serio/olpc_apsp.c
> +++ b/drivers/input/serio/olpc_apsp.c
> @@ -172,7 +172,6 @@ static int olpc_apsp_probe(struct platform_device *pdev)
> struct serio *kb_serio, *pad_serio;
> struct olpc_apsp *priv;
> struct resource *res;
> - struct device_node *np;
> unsigned long l;
> int error;
>
> @@ -180,7 +179,6 @@ static int olpc_apsp_probe(struct platform_device *pdev)
> if (!priv)
> return -ENOMEM;
>
> - np = pdev->dev.of_node;
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> priv->base = devm_ioremap_resource(&pdev->dev, res);
> if (IS_ERR(priv->base)) {
> --
> 2.17.1
^ permalink raw reply
* [PATCH] input: olpc_apsp: remove unused pointer 'np'
From: Colin King @ 2018-08-28 14:56 UTC (permalink / raw)
To: Dmitry Torokhov, linux-input; +Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
Pointer 'nb' is being assigned but is never used hence it is
redundant and can be removed.
Cleans up clang warning:
warning: variable 'np' set but not used [-Wunused-but-set-variable]
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
drivers/input/serio/olpc_apsp.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/input/serio/olpc_apsp.c b/drivers/input/serio/olpc_apsp.c
index 8e9a4209fcad..8bd8ed25946f 100644
--- a/drivers/input/serio/olpc_apsp.c
+++ b/drivers/input/serio/olpc_apsp.c
@@ -172,7 +172,6 @@ static int olpc_apsp_probe(struct platform_device *pdev)
struct serio *kb_serio, *pad_serio;
struct olpc_apsp *priv;
struct resource *res;
- struct device_node *np;
unsigned long l;
int error;
@@ -180,7 +179,6 @@ static int olpc_apsp_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
- np = pdev->dev.of_node;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->base)) {
--
2.17.1
^ permalink raw reply related
* Re: [PATCH] HID: i2c-hid: Fix flooded incomplete report after S3 on Rayd touchscreen
From: Benjamin Tissoires @ 2018-08-28 12:38 UTC (permalink / raw)
To: Jiri Kosina
Cc: acelan.kao, Hans de Goede, Dmitry Torokhov, Aaron Ma,
open list:HID CORE LAYER, lkml
In-Reply-To: <nycvar.YFH.7.76.1808281346150.25787@cbobk.fhfr.pm>
On Tue, Aug 28, 2018 at 1:46 PM Jiri Kosina <jikos@kernel.org> wrote:
>
> On Tue, 21 Aug 2018, AceLan Kao wrote:
>
> > The incomplete report flooded after S3 and touchscreen becomes
> > malfunctioned.
> > [ 1367.646244] i2c_hid i2c-CUST0000:00: i2c_hid_get_input: incomplete report (58/18785)
> > [ 1367.649471] i2c_hid i2c-CUST0000:00: i2c_hid_get_input: incomplete report (58/28743)
> > [ 1367.651092] i2c_hid i2c-CUST0000:00: i2c_hid_get_input: incomplete report (58/26757)
> > [ 1367.652658] i2c_hid i2c-CUST0000:00: i2c_hid_get_input: incomplete report (58/52280)
> > [ 1367.654287] i2c_hid i2c-CUST0000:00: i2c_hid_get_input: incomplete report (58/56059)
> >
> > Adding device ID, 04F3:30CC, to the quirk to re-send report description
> > after resume.
> >
> > Cc: stable@vger.kernel.org
> > Signed-off-by: AceLan Kao <acelan.kao@canonical.com>
>
> Applied, thanks.
Just a quick note Jiri. Hans pointed me this morning to
https://bugzilla.redhat.com/show_bug.cgi?id=1622695
And I think we should apply the quirk unconditionally as it should be
safe to retrieve the HID descriptor at all times. I am planning on
working on that tomorrow or Thursday when I have access to the XPS
with i2c_hid devices attached to it.
Cheers,
Benjamin
>
> --
> Jiri Kosina
> SUSE Labs
>
^ permalink raw reply
* Re: [PATCH] HID: core: fix memory leak on probe
From: Jiri Kosina @ 2018-08-28 12:07 UTC (permalink / raw)
To: Stefan Agner; +Cc: benjamin.tissoires, linux-input, linux-kernel
In-Reply-To: <20180828112955.11318-1-stefan@agner.ch>
On Tue, 28 Aug 2018, Stefan Agner wrote:
> The dynamically allocted collection stack does not get freed in
> all situations. Make sure to also free the collection stack when
> using the parser in hid_open_report().
>
> Fixes: 08a8a7cf1459 ("HID: core: do not upper bound the collection stack")
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
> Found with kmemleak:
>
> unreferenced object 0xc57f0700 (size 64):
> comm "kworker/0:1", pid 20, jiffies 131383 (age 28.750s)
> hex dump (first 32 bytes):
> 02 00 00 00 00 02 00 00 00 00 00 00 00 68 80 c5 .............h..
> 80 07 7f c5 01 00 00 00 08 48 80 c5 08 48 80 c5 .........H...H..
> backtrace:
> [<1b437483>] __kmalloc_track_caller+0x1dc/0x300
> [<ecd3baad>] krealloc+0x54/0xc0
> [<c565bd75>] hid_parser_main+0x258/0x2c8
> [<210b9aaa>] hid_open_report+0x134/0x2ac
> [<61cd8964>] hid_generic_probe+0x20/0x38
> [<e02107d6>] hid_device_probe+0xdc/0x13c
> [<334f035e>] really_probe+0x1d8/0x2c4
> [<351dc2c0>] driver_probe_device+0x68/0x184
> [<7e3e3d3c>] __device_attach_driver+0xa0/0xd4
> [<1b053a89>] bus_for_each_drv+0x60/0xc0
> [<732716d8>] __device_attach+0xdc/0x144
> [<dd3a0e76>] device_initial_probe+0x14/0x18
> [<f3a47b76>] bus_probe_device+0x90/0x98
> [<d5a1f0b4>] device_add+0x424/0x62c
> [<46595a15>] hid_add_device+0x108/0x2b8
> [<a0e2824c>] usbhid_probe+0x2d4/0x3bc
Also queued for 4.19. Thank you Stefan,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: input: fix leaking custom input node name
From: Jiri Kosina @ 2018-08-28 12:06 UTC (permalink / raw)
To: Stefan Agner; +Cc: benjamin.tissoires, linux-input, linux-kernel, stable
In-Reply-To: <20180828112955.11318-2-stefan@agner.ch>
On Tue, 28 Aug 2018, Stefan Agner wrote:
> Make sure to free the custom input node name on disconnect.
>
> Cc: stable@vger.kernel.org # v4.18+
> Fixes: c554bb045511 ("HID: input: append a suffix matching the application")
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
> Found with kmemleak, after unplugging a Logitech Unifying receiver:
>
> unreferenced object 0xc2345b80 (size 64):
> comm "kworker/0:1", pid 20, jiffies 4294955181 (age 320.740s)
> hex dump (first 32 bytes):
> 4c 6f 67 69 74 65 63 68 20 55 53 42 20 52 65 63 Logitech USB Rec
> 65 69 76 65 72 20 53 79 73 74 65 6d 20 43 6f 6e eiver System Con
> backtrace:
> [<8fec5a71>] __kmalloc_track_caller+0x1dc/0x300
> [<5b926275>] kvasprintf+0x60/0xcc
> [<21fc360f>] kasprintf+0x38/0x54
> [<3b6ce9f0>] hidinput_connect+0x23a8/0x4c60
> [<deaab707>] hid_connect+0x30c/0x38c
> [<5a28f7c9>] hid_hw_start+0x44/0x64
> [<267d70e8>] hid_generic_probe+0x34/0x38
> [<d68c31b1>] hid_device_probe+0xdc/0x13c
> [<09414e91>] really_probe+0x1d8/0x2c4
> [<f9d7157f>] driver_probe_device+0x68/0x184
> [<1def17c8>] __device_attach_driver+0xa0/0xd4
> [<d3b2081b>] bus_for_each_drv+0x60/0xc0
> [<379d02f8>] __device_attach+0xdc/0x144
> [<7026ace5>] device_initial_probe+0x14/0x18
> [<44527d01>] bus_probe_device+0x90/0x98
> [<cf58bf2f>] device_add+0x424/0x62c
>
> drivers/hid/hid-input.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
> index 4e94ea3e280a..ac201817a2dd 100644
> --- a/drivers/hid/hid-input.c
> +++ b/drivers/hid/hid-input.c
> @@ -1815,6 +1815,7 @@ void hidinput_disconnect(struct hid_device *hid)
> input_unregister_device(hidinput->input);
> else
> input_free_device(hidinput->input);
> + kfree(hidinput->name);
> kfree(hidinput);
Applied for 4.19, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] [v2] HID: add support for Apple Magic Keyboards
From: Jiri Kosina @ 2018-08-28 11:53 UTC (permalink / raw)
To: Sean O'Brien
Cc: Dmitry Torokhov, Benjamin Tissoires, linux-kernel, linux-input
In-Reply-To: <20180827200215.172838-1-seobrien@chromium.org>
On Mon, 27 Aug 2018, Sean O'Brien wrote:
> USB device
> Vendor 05ac (Apple)
> Device 026c (Magic Keyboard with Numeric Keypad)
>
> Bluetooth devices
> Vendor 004c (Apple)
> Device 0267 (Magic Keyboard)
> Device 026c (Magic Keyboard with Numeric Keypad)
>
> Support already exists for the Magic Keyboard over USB connection.
> Add support for the Magic Keyboard over Bluetooth connection, and for
> the Magic Keyboard with Numeric Keypad over Bluetooth and USB
> connection.
>
> Signed-off-by: Sean O'Brien <seobrien@chromium.org>
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: i2c-hid: Fix flooded incomplete report after S3 on Rayd touchscreen
From: Jiri Kosina @ 2018-08-28 11:46 UTC (permalink / raw)
To: AceLan Kao
Cc: Benjamin Tissoires, Hans de Goede, Dmitry Torokhov, Aaron Ma,
linux-input, linux-kernel
In-Reply-To: <20180821085513.13739-1-acelan.kao@canonical.com>
On Tue, 21 Aug 2018, AceLan Kao wrote:
> The incomplete report flooded after S3 and touchscreen becomes
> malfunctioned.
> [ 1367.646244] i2c_hid i2c-CUST0000:00: i2c_hid_get_input: incomplete report (58/18785)
> [ 1367.649471] i2c_hid i2c-CUST0000:00: i2c_hid_get_input: incomplete report (58/28743)
> [ 1367.651092] i2c_hid i2c-CUST0000:00: i2c_hid_get_input: incomplete report (58/26757)
> [ 1367.652658] i2c_hid i2c-CUST0000:00: i2c_hid_get_input: incomplete report (58/52280)
> [ 1367.654287] i2c_hid i2c-CUST0000:00: i2c_hid_get_input: incomplete report (58/56059)
>
> Adding device ID, 04F3:30CC, to the quirk to re-send report description
> after resume.
>
> Cc: stable@vger.kernel.org
> Signed-off-by: AceLan Kao <acelan.kao@canonical.com>
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: intel-ish-hid: Enable Sunrise Point-H ish driver
From: Jiri Kosina @ 2018-08-28 11:41 UTC (permalink / raw)
To: Andreas Bosch
Cc: Srinivas Pandruvada, Benjamin Tissoires, Even Xu, linux-input,
linux-kernel
In-Reply-To: <20180817201614.11971-1-linux@progandy.de>
On Fri, 17 Aug 2018, Andreas Bosch wrote:
> Added PCI ID for Sunrise Point-H ISH.
>
> Signed-off-by: Andreas Bosch <linux@progandy.de>
> ---
> I hope this patch arrives correctly.
> ---
> drivers/hid/intel-ish-hid/ipc/hw-ish.h | 1 +
> drivers/hid/intel-ish-hid/ipc/pci-ish.c | 1 +
> 2 files changed, 2 insertions(+)
>
> diff --git a/drivers/hid/intel-ish-hid/ipc/hw-ish.h b/drivers/hid/intel-ish-hid/ipc/hw-ish.h
> index 97869b7410eb..da133716bed0 100644
> --- a/drivers/hid/intel-ish-hid/ipc/hw-ish.h
> +++ b/drivers/hid/intel-ish-hid/ipc/hw-ish.h
> @@ -29,6 +29,7 @@
> #define CNL_Ax_DEVICE_ID 0x9DFC
> #define GLK_Ax_DEVICE_ID 0x31A2
> #define CNL_H_DEVICE_ID 0xA37C
> +#define SPT_H_DEVICE_ID 0xA135
>
> #define REVISION_ID_CHT_A0 0x6
> #define REVISION_ID_CHT_Ax_SI 0x0
> diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> index a2c53ea3b5ed..c7b8eb32b1ea 100644
> --- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> +++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> @@ -38,6 +38,7 @@ static const struct pci_device_id ish_pci_tbl[] = {
> {PCI_DEVICE(PCI_VENDOR_ID_INTEL, CNL_Ax_DEVICE_ID)},
> {PCI_DEVICE(PCI_VENDOR_ID_INTEL, GLK_Ax_DEVICE_ID)},
> {PCI_DEVICE(PCI_VENDOR_ID_INTEL, CNL_H_DEVICE_ID)},
> + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, SPT_H_DEVICE_ID)},
> {0, }
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* [PATCH] HID: input: fix leaking custom input node name
From: Stefan Agner @ 2018-08-28 11:29 UTC (permalink / raw)
To: jikos, benjamin.tissoires; +Cc: linux-input, linux-kernel, Stefan Agner, stable
In-Reply-To: <20180828112955.11318-1-stefan@agner.ch>
Make sure to free the custom input node name on disconnect.
Cc: stable@vger.kernel.org # v4.18+
Fixes: c554bb045511 ("HID: input: append a suffix matching the application")
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
Found with kmemleak, after unplugging a Logitech Unifying receiver:
unreferenced object 0xc2345b80 (size 64):
comm "kworker/0:1", pid 20, jiffies 4294955181 (age 320.740s)
hex dump (first 32 bytes):
4c 6f 67 69 74 65 63 68 20 55 53 42 20 52 65 63 Logitech USB Rec
65 69 76 65 72 20 53 79 73 74 65 6d 20 43 6f 6e eiver System Con
backtrace:
[<8fec5a71>] __kmalloc_track_caller+0x1dc/0x300
[<5b926275>] kvasprintf+0x60/0xcc
[<21fc360f>] kasprintf+0x38/0x54
[<3b6ce9f0>] hidinput_connect+0x23a8/0x4c60
[<deaab707>] hid_connect+0x30c/0x38c
[<5a28f7c9>] hid_hw_start+0x44/0x64
[<267d70e8>] hid_generic_probe+0x34/0x38
[<d68c31b1>] hid_device_probe+0xdc/0x13c
[<09414e91>] really_probe+0x1d8/0x2c4
[<f9d7157f>] driver_probe_device+0x68/0x184
[<1def17c8>] __device_attach_driver+0xa0/0xd4
[<d3b2081b>] bus_for_each_drv+0x60/0xc0
[<379d02f8>] __device_attach+0xdc/0x144
[<7026ace5>] device_initial_probe+0x14/0x18
[<44527d01>] bus_probe_device+0x90/0x98
[<cf58bf2f>] device_add+0x424/0x62c
drivers/hid/hid-input.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 4e94ea3e280a..ac201817a2dd 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1815,6 +1815,7 @@ void hidinput_disconnect(struct hid_device *hid)
input_unregister_device(hidinput->input);
else
input_free_device(hidinput->input);
+ kfree(hidinput->name);
kfree(hidinput);
}
--
2.18.0
^ permalink raw reply related
* [PATCH] HID: core: fix memory leak on probe
From: Stefan Agner @ 2018-08-28 11:29 UTC (permalink / raw)
To: jikos, benjamin.tissoires; +Cc: linux-input, linux-kernel, Stefan Agner
The dynamically allocted collection stack does not get freed in
all situations. Make sure to also free the collection stack when
using the parser in hid_open_report().
Fixes: 08a8a7cf1459 ("HID: core: do not upper bound the collection stack")
Signed-off-by: Stefan Agner <stefan@agner.ch>
---
Found with kmemleak:
unreferenced object 0xc57f0700 (size 64):
comm "kworker/0:1", pid 20, jiffies 131383 (age 28.750s)
hex dump (first 32 bytes):
02 00 00 00 00 02 00 00 00 00 00 00 00 68 80 c5 .............h..
80 07 7f c5 01 00 00 00 08 48 80 c5 08 48 80 c5 .........H...H..
backtrace:
[<1b437483>] __kmalloc_track_caller+0x1dc/0x300
[<ecd3baad>] krealloc+0x54/0xc0
[<c565bd75>] hid_parser_main+0x258/0x2c8
[<210b9aaa>] hid_open_report+0x134/0x2ac
[<61cd8964>] hid_generic_probe+0x20/0x38
[<e02107d6>] hid_device_probe+0xdc/0x13c
[<334f035e>] really_probe+0x1d8/0x2c4
[<351dc2c0>] driver_probe_device+0x68/0x184
[<7e3e3d3c>] __device_attach_driver+0xa0/0xd4
[<1b053a89>] bus_for_each_drv+0x60/0xc0
[<732716d8>] __device_attach+0xdc/0x144
[<dd3a0e76>] device_initial_probe+0x14/0x18
[<f3a47b76>] bus_probe_device+0x90/0x98
[<d5a1f0b4>] device_add+0x424/0x62c
[<46595a15>] hid_add_device+0x108/0x2b8
[<a0e2824c>] usbhid_probe+0x2d4/0x3bc
drivers/hid/hid-core.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 3da354af7a0a..44a465db3f96 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1039,6 +1039,7 @@ int hid_open_report(struct hid_device *device)
hid_err(device, "unbalanced delimiter at end of report description\n");
goto err;
}
+ kfree(parser->collection_stack);
vfree(parser);
device->status |= HID_STAT_PARSED;
return 0;
@@ -1047,6 +1048,7 @@ int hid_open_report(struct hid_device *device)
hid_err(device, "item fetching failed at offset %d\n", (int)(end - start));
err:
+ kfree(parser->collection_stack);
vfree(parser);
hid_close_report(device);
return ret;
--
2.18.0
^ permalink raw reply related
* Re: [PATCH 1/3] Add the `REL_WHEEL_HI_RES` event code
From: Jiri Kosina @ 2018-08-28 9:02 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Matthew Wilcox, Harry Cutts, linux-input, LKML, Jiri Kosina,
Benjamin Tissoires, linux-doc, Jonathan Corbet
In-Reply-To: <20180823190124.GB53155@dtor-ws>
On Thu, 23 Aug 2018, Dmitry Torokhov wrote:
> > > + - 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 256ths of a millimeter.
> >
> > Is it too late to change this to an actual unit like micrometres?
>
> No love for imperial roots? Sure, micrometers would work too I think.
I don't really care strongly :) Is either of you going to update the
patch? Otherwise I'll just apply as-is.
Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH 3/3] Enable high-resolution scrolling on Logitech mice
From: Benjamin Tissoires @ 2018-08-28 8:47 UTC (permalink / raw)
To: hcutts
Cc: open list:HID CORE LAYER, lkml, jiri.kosina, Dmitry Torokhov,
Jiri Kosina
In-Reply-To: <20180823183057.247630-4-hcutts@chromium.org>
Hi Harry,
On Thu, Aug 23, 2018 at 8:31 PM Harry Cutts <hcutts@chromium.org> wrote:
>
> There are three features used by various Logitech mice for
> high-resolution scrolling: the fast scrolling bit in HID++ 1.0, and the
> x2120 and x2121 features in HID++ 2.0 and above. This patch supports
> all three, and uses the multiplier reported by the mouse for the HID++
> 2.0+ features.
>
> The full list of product IDs of mice which support high-resolution
> scrolling was provided by Logitech, but the patch was tested using the
> following mice (over both Bluetooth and Unifying where applicable):
>
> * HID++ 1.0: Anywhere MX, Performance MX
> * x2120: M560
> * x2121: MX Anywhere 2, MX Master 2S
>
> Signed-off-by: Harry Cutts <hcutts@chromium.org>
Patches 1 and 2 look fine (I'd rather have the micrometers too).
I have more concerns about this one.
My main issue is that this patch both reshuffle existing parts and add
new features, which makes it hard to review.
> ---
>
> drivers/hid/hid-ids.h | 15 ++
> drivers/hid/hid-logitech-hidpp.c | 341 ++++++++++++++++++++++++++++---
> drivers/hid/hid-quirks.c | 11 +
> 3 files changed, 340 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index 79bdf0c7e351..64fbe6174189 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -717,6 +717,21 @@
> #define USB_DEVICE_ID_LOGITECH_MOUSE_C01A 0xc01a
> #define USB_DEVICE_ID_LOGITECH_MOUSE_C05A 0xc05a
> #define USB_DEVICE_ID_LOGITECH_MOUSE_C06A 0xc06a
> +/*
> + * The following mice have different IDs over Bluetooth than Logitech Unifying
> + * protocol, hence the _BT suffix.
> + */
> +#define USB_DEVICE_ID_LOGITECH_MOUSE_M336_337_535_BT1 0xb014
> +#define USB_DEVICE_ID_LOGITECH_MOUSE_M336_337_535_BT2 0xb016
> +#define USB_DEVICE_ID_LOGITECH_MOUSE_M720_BT 0xb015
> +#define USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2_BT1 0xb013
> +#define USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2_BT2 0xb018
> +#define USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2_BT3 0xb01f
> +#define USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2S_BT 0xb01a
> +#define USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_BT1 0xb012
> +#define USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_BT2 0xb017
> +#define USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_BT3 0xb01e
> +#define USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_2S_BT 0xb019
> #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a
> #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211
> #define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215
> diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
> index 19cc980eebce..17598b87f1b7 100644
> --- a/drivers/hid/hid-logitech-hidpp.c
> +++ b/drivers/hid/hid-logitech-hidpp.c
> @@ -64,6 +64,14 @@ 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
>
> @@ -149,6 +157,7 @@ struct hidpp_device {
> unsigned long capabilities;
>
> struct hidpp_battery battery;
> + struct hid_scroll_counter vertical_wheel_counter;
> };
>
> /* HID++ 1.0 error codes */
> @@ -400,32 +409,53 @@ static void hidpp_prefix_name(char **name, int name_length)
> #define HIDPP_SET_LONG_REGISTER 0x82
> #define HIDPP_GET_LONG_REGISTER 0x83
>
> -#define HIDPP_REG_GENERAL 0x00
> -
> -static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev)
> +/**
> + * 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)
> {
> 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,
> - HIDPP_REG_GENERAL,
> - NULL, 0, &response);
> + REPORT_ID_HIDPP_SHORT,
> + HIDPP_GET_REGISTER,
> + register_address,
> + NULL, 0, &response);
> if (ret)
> return ret;
>
> memcpy(params, response.rap.params, 3);
>
> - /* Set the battery bit */
> - params[0] |= BIT(4);
> + params[byte] |= BIT(bit);
>
> return hidpp_send_rap_command_sync(hidpp_dev,
> - REPORT_ID_HIDPP_SHORT,
> - HIDPP_SET_REGISTER,
> - HIDPP_REG_GENERAL,
> - params, 3, &response);
> + 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);
> +}
This hunk should be dealt in a separate patch (including the one function below)
> +
> +#define HIDPP_REG_FEATURES 0x01
> +
> +/* On HID++ 1.0 devices, high-res scrolling was called "fast scrolling". */
> +static int hidpp10_enable_fast_scrolling(struct hidpp_device *hidpp_dev)
> +{
> + return hidpp10_set_register_bit(hidpp_dev, HIDPP_REG_FEATURES, 0, 6);
> }
>
> #define HIDPP_REG_BATTERY_STATUS 0x07
> @@ -1136,6 +1166,101 @@ 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 */
> /* -------------------------------------------------------------------------- */
> @@ -2399,7 +2524,8 @@ 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);
> - input_report_rel(mydata->input, REL_WHEEL, v);
> + hid_scroll_counter_handle_scroll(
> + &hidpp->vertical_wheel_counter, v);
The conversion input_report_rel(... REL_WHEEL,...) to
hid_scroll_counter_handle_scroll() should be dealt in a separate
patch.
>
> input_sync(mydata->input);
> }
> @@ -2527,6 +2653,71 @@ 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.
> + * @mm256_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 mm256_per_hi_res_unit;
> +};
> +
> +static struct hi_res_scroll_info hi_res_scroll_devices[] = {
> + { /* Anywhere MX */
> + .product_id = 0x1017, .mm256_per_hi_res_unit = 114 },
> + { /* Performance MX */
> + .product_id = 0x101a, .mm256_per_hi_res_unit = 104 },
> + { /* M560 */
> + .product_id = 0x402d, .mm256_per_hi_res_unit = 111 },
> + { /* MX Master 2S */
> + .product_id = 0x4069, .mm256_per_hi_res_unit = 104 },
> + { .product_id = USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_2S_BT,
> + .mm256_per_hi_res_unit = 104 },
> +};
> +
> +static int hi_res_scroll_look_up_mm256(__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].mm256_per_hi_res_unit;
> + }
> + return 104;
104?
> +}
> +
> +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_fast_scrolling(hidpp);
> + multiplier = 8;
> + }
> + if (ret)
> + return ret;
> +
> + hidpp->vertical_wheel_counter.resolution_multiplier = multiplier;
> + hidpp->vertical_wheel_counter.mm256_per_hi_res_unit =
> + hi_res_scroll_look_up_mm256(hidpp->hid_dev->product);
> + return 0;
> +}
> +
> /* -------------------------------------------------------------------------- */
> /* Generic HID++ devices */
> /* -------------------------------------------------------------------------- */
> @@ -2572,6 +2763,11 @@ 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,
> @@ -2690,6 +2886,25 @@ 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)
> +{
> + 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;
You are using usage_table to force the .event function to be called
only on the WHEEL events. This is correct, but I have a feeling this
will be harder to understand when we are going to extend the .event()
function for other events.
If you rather keep the cde that way, please add a comment at the
beginning of the function stating that we are only called against
WHEEL events because of usage_table.
> +
> + 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);
> @@ -2901,6 +3116,9 @@ 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;
> @@ -3086,35 +3304,97 @@ 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,
> - USB_VENDOR_ID_LOGITECH, 0x4011),
> + LDJ_DEVICE(0x4011),
> .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT |
> HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS },
> { /* wireless touchpad T650 */
> - HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
> - USB_VENDOR_ID_LOGITECH, 0x4101),
> + LDJ_DEVICE(0x4101),
The rewrite of the existing supported devices should be in a separate patch too.
> .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT },
> { /* wireless touchpad T651 */
> 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 M336, M337, and M535 */
> + HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
> + USB_DEVICE_ID_LOGITECH_MOUSE_M336_337_535_BT1),
> + .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
> + USB_DEVICE_ID_LOGITECH_MOUSE_M336_337_535_BT2),
> + .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 */
> - HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
> - USB_VENDOR_ID_LOGITECH, 0x402d),
> - .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_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 },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
> + USB_DEVICE_ID_LOGITECH_MOUSE_M720_BT),
> + .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 },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
> + USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2_BT1),
> + .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
> + USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2_BT2),
> + .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
> + USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2_BT3),
> + .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
> + { /* Mouse Logitech MX Anywhere 2S */
> + LDJ_DEVICE(0x406a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
> + USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2S_BT),
> + .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 },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
> + USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_BT1),
> + .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
> + USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_BT2),
> + .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
> + USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_BT3),
> + .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
> + { /* Mouse Logitech MX Master 2S */
> + LDJ_DEVICE(0x4069), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
> + USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_2S_BT),
> + .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
> + { /* Mouse Logitech Performance MX */
> + LDJ_DEVICE(0x101a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
> { /* Keyboard logitech K400 */
> - HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
> - USB_VENDOR_ID_LOGITECH, 0x4024),
> + LDJ_DEVICE(0x4024),
> .driver_data = HIDPP_QUIRK_CLASS_K400 },
> { /* Solar Keyboard Logitech K750 */
> - HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
> - USB_VENDOR_ID_LOGITECH, 0x4002),
> + LDJ_DEVICE(0x4002),
> .driver_data = HIDPP_QUIRK_CLASS_K750 },
>
> - { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
> - USB_VENDOR_ID_LOGITECH, HID_ANY_ID)},
> + { LDJ_DEVICE(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},
> @@ -3123,12 +3403,19 @@ 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,
> diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
> index 249d49b6b16c..7926c275f258 100644
> --- a/drivers/hid/hid-quirks.c
> +++ b/drivers/hid/hid-quirks.c
> @@ -463,6 +463,17 @@ static const struct hid_device_id hid_have_special_driver[] = {
> #endif
> #if IS_ENABLED(CONFIG_HID_LOGITECH_HIDPP)
> { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_T651) },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_M336_337_535_BT1) },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_M336_337_535_BT2) },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_M720_BT) },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2_BT1) },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2_BT2) },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2_BT3) },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_ANYWHERE_2S_BT) },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_BT1) },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_BT2) },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_BT3) },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_MX_MASTER_2S_BT) },
Since v4.16, this should not be required anymore. Please drop the hunk
if I am correct.
Cheers,
Benjamin
> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL) },
> #endif
> #if IS_ENABLED(CONFIG_HID_LOGITECH_DJ)
> --
> 2.18.0.1017.ga543ac7ca45-goog
>
^ permalink raw reply
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