Skip to content

Commit

Permalink
Apply fix from @johnchen902
Browse files Browse the repository at this point in the history
This fix removes the need for external files to load the driver. It turns out the driver already loaded itself, but without a delay it would fail. This is now fixed.

Based on the work seen here johnchen902/linux@cb700d0
  • Loading branch information
RicardoEPRodrigues committed Jun 7, 2021
1 parent dd4d31f commit e050c13
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 104 deletions.
8 changes: 1 addition & 7 deletions build-deb.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,10 @@ ETC_DIR="/etc"
PKG_DIR="/pkg-debian"
OPT_DIR="/opt/magicmouse-hid"

DEB="magicmouse-hid_1.1.0-0.deb"
DEB="magicmouse-hid_2.0.0-0.deb"

cp -rf ${DIR}${ETC_DIR} ${DIR}${PKG_DIR}

mkdir -p ${DIR}${PKG_DIR}${OPT_DIR}
# Copy scripts to /opt
cp -f ${DIR}/scripts/magic-mouse-2-add.sh ${DIR}${PKG_DIR}${OPT_DIR}/magic-mouse-2-add.sh
# cp -f ${DIR}/install.sh ${DIR}${PKG_DIR}${OPT_DIR}/install.sh
# cp -f ${DIR}/remove.sh ${DIR}${PKG_DIR}${OPT_DIR}/remove.sh

mkdir -p ${DIR}${PKG_DIR}${OPT_DIR}/scripts
cp -f ${DIR}/scripts/install.sh ${DIR}${PKG_DIR}${OPT_DIR}/scripts/install.sh
cp -f ${DIR}/scripts/remove.sh ${DIR}${PKG_DIR}${OPT_DIR}/scripts/remove.sh
Expand Down
9 changes: 0 additions & 9 deletions etc/udev/rules.d/10-magicmouse.rules

This file was deleted.

16 changes: 4 additions & 12 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ set -e
set -x

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
OPT_DIR="/opt/magicmouse-hid"
UDEV_DIR="/etc/udev/rules.d"
MODPROBE_DIR="/etc/modprobe.d"


Expand All @@ -21,17 +19,11 @@ cp -f ${DIR}${MODPROBE_DIR}/hid-magicmouse.conf ${MODPROBE_DIR}/hid-magicmouse.c
chmod u+x ${DIR}/scripts/install.sh
${DIR}/scripts/install.sh

# Copy script to load the driver to OPT directory
mkdir -p ${OPT_DIR}
cp -f ${DIR}/scripts/magic-mouse-2-add.sh ${OPT_DIR}/magic-mouse-2-add.sh
chmod +x ${OPT_DIR}/magic-mouse-2-add.sh

# Copy udev rule and reload udev
cp -f ${DIR}${UDEV_DIR}/10-magicmouse.rules ${UDEV_DIR}/10-magicmouse.rules
udevadm control -R

# Disable eSCO mode in Bluetooth to fix disconnection problems with the mouse
echo 1 | tee /sys/module/bluetooth/parameters/disable_esco
systemctl restart bluetooth
# persist eSCO mode in Bluetooth setting
echo "options bluetooth disable_esco=1" | tee /etc/modprobe.d/bluetooth-tweaks.conf
echo "options bluetooth disable_esco=1" | tee /etc/modprobe.d/bluetooth-tweaks.conf

# Load driver
sudo modprobe -a hid_magicmouse
127 changes: 87 additions & 40 deletions linux/drivers/hid/hid-magicmouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <linux/input/mt.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb/input.h>
#include <linux/workqueue.h>

#include "hid-ids.h"

Expand Down Expand Up @@ -168,6 +168,9 @@ struct magicmouse_sc {
u8 size;
} touches[MAX_TOUCHES];
int tracking_ids[MAX_TOUCHES];

struct hid_device *hdev;
struct delayed_work work;
};

static int magicmouse_firm_touch(struct magicmouse_sc *msc)
Expand Down Expand Up @@ -570,6 +573,21 @@ static int magicmouse_raw_event(struct hid_device *hdev,
return 1;
}

static int magicmouse_event(struct hid_device *hdev, struct hid_field *field,
struct hid_usage *usage, __s32 value)
{
struct magicmouse_sc *msc = hid_get_drvdata(hdev);
if (msc->input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 &&
field->report->id == MOUSE2_REPORT_ID) {
// magic_mouse_raw_event has done all the work. Skip hidinput.
//
// Specifically, hidinput may modify BTN_LEFT and BTN_RIGHT,
// breaking emulate_3button.
return 1;
}
return 0;
}

static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev)
{
int error;
Expand Down Expand Up @@ -743,26 +761,66 @@ static int magicmouse_input_configured(struct hid_device *hdev,
}



static int magicmouse_enable_multitouch(struct hid_device *hdev)
{
const u8 *feature;
const u8 feature_mt[] = { 0xD7, 0x01 };
const u8 feature_mt_mouse2[] = { 0xF1, 0x02, 0x01 };
const u8 feature_mt_trackpad2_usb[] = { 0x02, 0x01 };
const u8 feature_mt_trackpad2_bt[] = { 0xF1, 0x02, 0x01 };
u8 *buf;
int ret;
int feature_size;

if (hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
if (hdev->vendor == BT_VENDOR_ID_APPLE) {
feature_size = sizeof(feature_mt_trackpad2_bt);
feature = feature_mt_trackpad2_bt;
} else { /* USB_VENDOR_ID_APPLE */
feature_size = sizeof(feature_mt_trackpad2_usb);
feature = feature_mt_trackpad2_usb;
}
} else if (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
feature_size = sizeof(feature_mt_mouse2);
feature = feature_mt_mouse2;
} else {
feature_size = sizeof(feature_mt);
feature = feature_mt;
}

buf = kmemdup(feature, feature_size, GFP_KERNEL);
if (!buf)
return -ENOMEM;

ret = hid_hw_raw_request(hdev, buf[0], buf, feature_size,
HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
kfree(buf);
return ret;
}

static void magicmouse_enable_mt_work(struct work_struct *work)
{
struct magicmouse_sc *msc =
container_of(work, struct magicmouse_sc, work.work);
int ret;

ret = magicmouse_enable_multitouch(msc->hdev);
if (ret < 0)
hid_err(msc->hdev, "unable to request touch data (%d)\n", ret);
}

static int magicmouse_probe(struct hid_device *hdev,
const struct hid_device_id *id)
{
__u8 feature_mt_mouse2_bt[] = { 0xF1, 0x02, 0x01 };
__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;
struct usb_interface *intf;

if (id->vendor == USB_VENDOR_ID_APPLE &&
id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
intf = to_usb_interface(hdev->dev.parent);
if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
return 0;
}
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) {
Expand All @@ -771,6 +829,8 @@ static int magicmouse_probe(struct hid_device *hdev,
}

msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
msc->hdev = hdev;
INIT_DEFERRABLE_WORK(&msc->work, magicmouse_enable_mt_work);

msc->quirks = id->driver_data;
hid_set_drvdata(hdev, msc);
Expand Down Expand Up @@ -829,43 +889,28 @@ 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.
*/
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 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2){
feature_size = sizeof(feature_mt_mouse2_bt);
feature = kmemdup(feature_mt_mouse2_bt, 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) {
ret = magicmouse_enable_multitouch(hdev);
if (ret != -EIO && ret < 0) {
hid_err(hdev, "unable to request touch data (%d)\n", ret);
goto err_stop_hw;
}
if (ret == -EIO && id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2) {
schedule_delayed_work(&msc->work, msecs_to_jiffies(500));
}

return 0;
err_stop_hw:
hid_hw_stop(hdev);
return ret;
}

static void magicmouse_remove(struct hid_device *hdev)
{
struct magicmouse_sc *msc = hid_get_drvdata(hdev);
cancel_delayed_work_sync(&msc->work);
hid_hw_stop(hdev);
}

static const struct hid_device_id magic_mice[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 },
Expand All @@ -885,7 +930,9 @@ static struct hid_driver magicmouse_driver = {
.name = "magicmouse",
.id_table = magic_mice,
.probe = magicmouse_probe,
.remove = magicmouse_remove,
.raw_event = magicmouse_raw_event,
.event = magicmouse_event,
.input_mapping = magicmouse_input_mapping,
.input_configured = magicmouse_input_configured,
};
Expand Down
7 changes: 2 additions & 5 deletions pkg-debian/DEBIAN/postinst
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@ cd ${DIR}
chmod u+x ${DIR}/scripts/install.sh
${DIR}/scripts/install.sh

# Copy script to load the driver to OPT directory
chmod +x ${DIR}/magic-mouse-2-add.sh

# Copy udev rule and reload udev
udevadm control -R
# Load driver
sudo modprobe -a hid_magicmouse

# Disable eSCO mode in Bluetooth to fix disconnection problems with the mouse
echo 1 | tee /sys/module/bluetooth/parameters/disable_esco
Expand Down
4 changes: 2 additions & 2 deletions pkg-debian/DEBIAN/prerm
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ cd ${DIR}
chmod u+x ${DIR}/scripts/remove.sh
${DIR}/scripts/remove.sh

# Reload udev after removing the udev rule
udevadm control -R
# Remove loaded driver
modprobe -r hid_magicmouse

# Restart Bluetooth
systemctl restart bluetooth
17 changes: 8 additions & 9 deletions remove.sh
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
#!/bin/bash

if [ "$EUID" -ne 0 ]
then echo "Please run as root"
exit
fi

set -e
set -x

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
OPT_DIR="/opt/magicmouse-hid"
UDEV_DIR="/etc/udev/rules.d"
MODPROBE_DIR="/etc/modprobe.d"

# Remove drive through DKMS
chmod u+x ${DIR}/scripts/remove.sh
${DIR}/scripts/remove.sh

# Remove loaded driver
modprobe -r hid_magicmouse

# Remove Modprobe configuration file
rm -f ${MODPROBE_DIR}/hid-magicmouse.conf

# Copy `.ko` and script to activate it to OPT directory
rm -rf ${OPT_DIR}

# Remove the udev rule and reload udev
rm -f ${UDEV_DIR}/10-magicmouse.rules
udevadm control -R

# Restart Bluetooth
systemctl restart bluetooth
20 changes: 0 additions & 20 deletions scripts/magic-mouse-2-add.sh

This file was deleted.

0 comments on commit e050c13

Please sign in to comment.