Commit 9bdc30e3 authored by Aditya Garg's avatar Aditya Garg Committed by Jiri Kosina
Browse files

HID: magicmouse: avoid setting up battery timer when not needed



Currently, the battery timer is set up for all devices using
hid-magicmouse, irrespective of whether they actually need it or not.

The current implementation requires the battery timer for Magic Mouse 2
and Magic Trackpad 2 when connected via USB only. Add checks to ensure
that the battery timer is only set up when they are connected via USB.

Fixes: 0b91b4e4 ("HID: magicmouse: Report battery level over USB")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarAditya Garg <gargaditya08@live.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.com>
parent c061046f
Loading
Loading
Loading
Loading
+39 −23
Original line number Diff line number Diff line
@@ -791,17 +791,31 @@ static void magicmouse_enable_mt_work(struct work_struct *work)
		hid_err(msc->hdev, "unable to request touch data (%d)\n", ret);
}

static bool is_usb_magicmouse2(__u32 vendor, __u32 product)
{
	if (vendor != USB_VENDOR_ID_APPLE)
		return false;
	return product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
	       product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC;
}

static bool is_usb_magictrackpad2(__u32 vendor, __u32 product)
{
	if (vendor != USB_VENDOR_ID_APPLE)
		return false;
	return product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
	       product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC;
}

static int magicmouse_fetch_battery(struct hid_device *hdev)
{
#ifdef CONFIG_HID_BATTERY_STRENGTH
	struct hid_report_enum *report_enum;
	struct hid_report *report;

	if (!hdev->battery || hdev->vendor != USB_VENDOR_ID_APPLE ||
	    (hdev->product != USB_DEVICE_ID_APPLE_MAGICMOUSE2 &&
	     hdev->product != USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC &&
	     hdev->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
	     hdev->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC))
	if (!hdev->battery ||
	    (!is_usb_magicmouse2(hdev->vendor, hdev->product) &&
	     !is_usb_magictrackpad2(hdev->vendor, hdev->product)))
		return -1;

	report_enum = &hdev->report_enum[hdev->battery_report_type];
@@ -863,17 +877,17 @@ static int magicmouse_probe(struct hid_device *hdev,
		return ret;
	}

	if (is_usb_magicmouse2(id->vendor, id->product) ||
	    is_usb_magictrackpad2(id->vendor, id->product)) {
		timer_setup(&msc->battery_timer, magicmouse_battery_timer_tick, 0);
		mod_timer(&msc->battery_timer,
			  jiffies + msecs_to_jiffies(USB_BATTERY_TIMEOUT_MS));
		magicmouse_fetch_battery(hdev);
	}

	if (id->vendor == USB_VENDOR_ID_APPLE &&
	    (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
	     id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC ||
	     ((id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
	       id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) &&
	      hdev->type != HID_TYPE_USBMOUSE)))
	if (is_usb_magicmouse2(id->vendor, id->product) ||
	    (is_usb_magictrackpad2(id->vendor, id->product) &&
	     hdev->type != HID_TYPE_USBMOUSE))
		return 0;

	if (!msc->input) {
@@ -936,7 +950,10 @@ static int magicmouse_probe(struct hid_device *hdev,

	return 0;
err_stop_hw:
	if (is_usb_magicmouse2(id->vendor, id->product) ||
	    is_usb_magictrackpad2(id->vendor, id->product))
		timer_delete_sync(&msc->battery_timer);

	hid_hw_stop(hdev);
	return ret;
}
@@ -947,6 +964,8 @@ static void magicmouse_remove(struct hid_device *hdev)

	if (msc) {
		cancel_delayed_work_sync(&msc->work);
		if (is_usb_magicmouse2(hdev->vendor, hdev->product) ||
		    is_usb_magictrackpad2(hdev->vendor, hdev->product))
			timer_delete_sync(&msc->battery_timer);
	}

@@ -964,11 +983,8 @@ static const __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
	 *   0x05, 0x01,       // Usage Page (Generic Desktop)        0
	 *   0x09, 0x02,       // Usage (Mouse)                       2
	 */
	if (hdev->vendor == USB_VENDOR_ID_APPLE &&
	    (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
	     hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC ||
	     hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
	     hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) &&
	if ((is_usb_magicmouse2(hdev->vendor, hdev->product) ||
	     is_usb_magictrackpad2(hdev->vendor, hdev->product)) &&
	    *rsize == 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) {
		hid_info(hdev,
			 "fixing up magicmouse battery report descriptor\n");