@@ -59,6 +59,8 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
5959#define MOUSE_REPORT_ID 0x29
6060#define MOUSE2_REPORT_ID 0x12
6161#define DOUBLE_REPORT_ID 0xf7
62+ #define USB_BATTERY_TIMEOUT_MS 60000
63+
6264/* These definitions are not precise, but they're close enough. (Bits
6365 * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem
6466 * to be some kind of bit mask -- 0x20 may be a near-field reading,
@@ -142,6 +144,7 @@ struct magicmouse_sc {
142144
143145 struct hid_device * hdev ;
144146 struct delayed_work work ;
147+ struct timer_list battery_timer ;
145148};
146149
147150static int magicmouse_firm_touch (struct magicmouse_sc * msc )
@@ -752,18 +755,51 @@ static void magicmouse_enable_mt_work(struct work_struct *work)
752755 hid_err (msc -> hdev , "unable to request touch data (%d)\n" , ret );
753756}
754757
758+ static int magicmouse_fetch_battery (struct hid_device * hdev )
759+ {
760+ #ifdef CONFIG_HID_BATTERY_STRENGTH
761+ struct hid_report_enum * report_enum ;
762+ struct hid_report * report ;
763+
764+ if (!hdev -> battery || hdev -> vendor != USB_VENDOR_ID_APPLE ||
765+ (hdev -> product != USB_DEVICE_ID_APPLE_MAGICMOUSE2 &&
766+ hdev -> product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ))
767+ return -1 ;
768+
769+ report_enum = & hdev -> report_enum [hdev -> battery_report_type ];
770+ report = report_enum -> report_id_hash [hdev -> battery_report_id ];
771+
772+ if (!report || report -> maxfield < 1 )
773+ return -1 ;
774+
775+ if (hdev -> battery_capacity == hdev -> battery_max )
776+ return -1 ;
777+
778+ hid_hw_request (hdev , report , HID_REQ_GET_REPORT );
779+ return 0 ;
780+ #else
781+ return -1 ;
782+ #endif
783+ }
784+
785+ static void magicmouse_battery_timer_tick (struct timer_list * t )
786+ {
787+ struct magicmouse_sc * msc = from_timer (msc , t , battery_timer );
788+ struct hid_device * hdev = msc -> hdev ;
789+
790+ if (magicmouse_fetch_battery (hdev ) == 0 ) {
791+ mod_timer (& msc -> battery_timer ,
792+ jiffies + msecs_to_jiffies (USB_BATTERY_TIMEOUT_MS ));
793+ }
794+ }
795+
755796static int magicmouse_probe (struct hid_device * hdev ,
756797 const struct hid_device_id * id )
757798{
758799 struct magicmouse_sc * msc ;
759800 struct hid_report * report ;
760801 int ret ;
761802
762- if (id -> vendor == USB_VENDOR_ID_APPLE &&
763- id -> product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
764- hdev -> type != HID_TYPE_USBMOUSE )
765- return - ENODEV ;
766-
767803 msc = devm_kzalloc (& hdev -> dev , sizeof (* msc ), GFP_KERNEL );
768804 if (msc == NULL ) {
769805 hid_err (hdev , "can't alloc magicmouse descriptor\n" );
@@ -789,6 +825,16 @@ static int magicmouse_probe(struct hid_device *hdev,
789825 return ret ;
790826 }
791827
828+ timer_setup (& msc -> battery_timer , magicmouse_battery_timer_tick , 0 );
829+ mod_timer (& msc -> battery_timer ,
830+ jiffies + msecs_to_jiffies (USB_BATTERY_TIMEOUT_MS ));
831+ magicmouse_fetch_battery (hdev );
832+
833+ if (id -> vendor == USB_VENDOR_ID_APPLE &&
834+ (id -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
835+ (id -> product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 && hdev -> type != HID_TYPE_USBMOUSE )))
836+ return 0 ;
837+
792838 if (!msc -> input ) {
793839 hid_err (hdev , "magicmouse input not registered\n" );
794840 ret = - ENOMEM ;
@@ -841,6 +887,7 @@ static int magicmouse_probe(struct hid_device *hdev,
841887
842888 return 0 ;
843889err_stop_hw :
890+ del_timer_sync (& msc -> battery_timer );
844891 hid_hw_stop (hdev );
845892 return ret ;
846893}
@@ -849,17 +896,52 @@ static void magicmouse_remove(struct hid_device *hdev)
849896{
850897 struct magicmouse_sc * msc = hid_get_drvdata (hdev );
851898
852- if (msc )
899+ if (msc ) {
853900 cancel_delayed_work_sync (& msc -> work );
901+ del_timer_sync (& msc -> battery_timer );
902+ }
854903
855904 hid_hw_stop (hdev );
856905}
857906
907+ static __u8 * magicmouse_report_fixup (struct hid_device * hdev , __u8 * rdesc ,
908+ unsigned int * rsize )
909+ {
910+ /*
911+ * Change the usage from:
912+ * 0x06, 0x00, 0xff, // Usage Page (Vendor Defined Page 1) 0
913+ * 0x09, 0x0b, // Usage (Vendor Usage 0x0b) 3
914+ * To:
915+ * 0x05, 0x01, // Usage Page (Generic Desktop) 0
916+ * 0x09, 0x02, // Usage (Mouse) 2
917+ */
918+ if (hdev -> vendor == USB_VENDOR_ID_APPLE &&
919+ (hdev -> product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
920+ hdev -> product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ) &&
921+ * rsize == 83 && rdesc [46 ] == 0x84 && rdesc [58 ] == 0x85 ) {
922+ hid_info (hdev ,
923+ "fixing up magicmouse battery report descriptor\n" );
924+ * rsize = * rsize - 1 ;
925+ rdesc = kmemdup (rdesc + 1 , * rsize , GFP_KERNEL );
926+ if (!rdesc )
927+ return NULL ;
928+
929+ rdesc [0 ] = 0x05 ;
930+ rdesc [1 ] = 0x01 ;
931+ rdesc [2 ] = 0x09 ;
932+ rdesc [3 ] = 0x02 ;
933+ }
934+
935+ return rdesc ;
936+ }
937+
858938static const struct hid_device_id magic_mice [] = {
859939 { HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_APPLE ,
860940 USB_DEVICE_ID_APPLE_MAGICMOUSE ), .driver_data = 0 },
861941 { HID_BLUETOOTH_DEVICE (BT_VENDOR_ID_APPLE ,
862942 USB_DEVICE_ID_APPLE_MAGICMOUSE2 ), .driver_data = 0 },
943+ { HID_USB_DEVICE (USB_VENDOR_ID_APPLE ,
944+ USB_DEVICE_ID_APPLE_MAGICMOUSE2 ), .driver_data = 0 },
863945 { HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_APPLE ,
864946 USB_DEVICE_ID_APPLE_MAGICTRACKPAD ), .driver_data = 0 },
865947 { HID_BLUETOOTH_DEVICE (BT_VENDOR_ID_APPLE ,
@@ -875,6 +957,7 @@ static struct hid_driver magicmouse_driver = {
875957 .id_table = magic_mice ,
876958 .probe = magicmouse_probe ,
877959 .remove = magicmouse_remove ,
960+ .report_fixup = magicmouse_report_fixup ,
878961 .raw_event = magicmouse_raw_event ,
879962 .event = magicmouse_event ,
880963 .input_mapping = magicmouse_input_mapping ,
0 commit comments