All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alec Hall <signshop.alec@gmail.com>
To: Jiri Kosina <jikos@kernel.org>,
	Benjamin Tissoires <bentiss@kernel.org>,
	linux-input@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Alec Hall <signshop.alec@gmail.com>
Subject: [PATCH 3/3] HID: magicmouse: report charge status over Bluetooth
Date: Tue, 14 Jul 2026 06:12:35 -0400	[thread overview]
Message-ID: <20260714101235.99447-4-signshop.alec@gmail.com> (raw)
In-Reply-To: <20260714101235.99447-1-signshop.alec@gmail.com>

Battery input report 0x90 carries a status byte that the generic HID
battery code does not map to HID_BAT_CHARGING, so charge_status keeps
its POWER_SUPPLY_STATUS_DISCHARGING default and user space never learns
whether the device is on external power (e.g. a Magic Trackpad 2 shows
"discharging" by default even while charging, and cannot report
"discharging" the moment the cable is pulled at 100%).

Parse the status byte in raw_event and set the battery charge status
accordingly (bit 1 = external power, bit 0 = charge complete), notifying
user space with power_supply_changed(). The bit meanings were determined
by observation on a Magic Trackpad 2 rather than from documentation.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Alec Hall <signshop.alec@gmail.com>
---
 drivers/hid/hid-magicmouse.c | 37 ++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 6d0e76314b10..8bb791efef3a 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
+#include <linux/power_supply.h>
 
 #include "hid-ids.h"
 
@@ -60,6 +61,10 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
 #define MOUSE_REPORT_ID    0x29
 #define MOUSE2_REPORT_ID   0x12
 #define DOUBLE_REPORT_ID   0xf7
+/* Battery Input Report 0x90 = [report_id, status, capacity]. */
+#define MAGICMOUSE_BATTERY_REPORT_ID	0x90
+#define MAGICMOUSE_BATTERY_POWERED	0x02	/* external power connected */
+#define MAGICMOUSE_BATTERY_CHARGED	0x01	/* charge complete (on charger) */
 #define USB_BATTERY_TIMEOUT_SEC 60
 
 /* These definitions are not precise, but they're close enough.  (Bits
@@ -383,6 +388,35 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
 	}
 }
 
+/*
+ * The battery report carries a charge-status byte the generic HID battery code
+ * doesn't map, so translate the vendor status bits into a power_supply status.
+ * This makes charging/discharging honest -- e.g. "discharging" as soon as the
+ * cable is pulled, even at 100%.
+ */
+static void magicmouse_report_charge_status(struct hid_device *hdev, u8 status)
+{
+#ifdef CONFIG_HID_BATTERY_STRENGTH
+	struct hid_battery *bat = hid_get_battery(hdev);
+	int cs;
+
+	if (!bat || !bat->ps)
+		return;
+
+	if (!(status & MAGICMOUSE_BATTERY_POWERED))
+		cs = POWER_SUPPLY_STATUS_DISCHARGING;
+	else if (status & MAGICMOUSE_BATTERY_CHARGED)
+		cs = POWER_SUPPLY_STATUS_FULL;
+	else
+		cs = POWER_SUPPLY_STATUS_CHARGING;
+
+	if (bat->charge_status != cs) {
+		bat->charge_status = cs;
+		power_supply_changed(bat->ps);
+	}
+#endif
+}
+
 static int magicmouse_raw_event(struct hid_device *hdev,
 		struct hid_report *report, u8 *data, int size)
 {
@@ -394,6 +428,9 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 	if (size < 1)
 		return 0;
 
+	if (data[0] == MAGICMOUSE_BATTERY_REPORT_ID && size >= 3)
+		magicmouse_report_charge_status(hdev, data[1]);
+
 	switch (data[0]) {
 	case TRACKPAD_REPORT_ID:
 	case TRACKPAD2_BT_REPORT_ID:
-- 
2.55.0


  parent reply	other threads:[~2026-07-14 10:12 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-14 10:12 [PATCH 0/3] HID: Apple Magic Keyboard/Trackpad battery over Bluetooth Alec Hall
2026-07-14 10:12 ` [PATCH 1/3] HID: apple: report Magic Keyboard " Alec Hall
2026-07-14 10:12 ` [PATCH 2/3] HID: magicmouse: report " Alec Hall
2026-07-14 10:12 ` Alec Hall [this message]
2026-07-14 10:25   ` [PATCH 3/3] HID: magicmouse: report charge status " sashiko-bot
2026-07-14 17:17     ` Alec Hall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260714101235.99447-4-signshop.alec@gmail.com \
    --to=signshop.alec@gmail.com \
    --cc=bentiss@kernel.org \
    --cc=jikos@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.