[PATCH] bcm5974-0.57 plus hack
Henrik Rydberg
rydberg at euromail.se
Mon Jul 21 20:41:32 UTC 2008
From: Henrik Rydberg <rydberg at euromail.se>
The usbhid_modify_dquirk function is not exported in hardy,
and trying to load the bcm5974 from the hardy-proposed LBM 2.6.24-20 simply
fails with an undefined-symbol error. This patch upgrades hardy-lbm to bcm5974-0.57,
and comments out the dynamic quirk addition, awaiting a possible addition of
EXPORT_SYMBOL(usbhid_modify_dquirk) in usbhid/hid-quirks.c.
Signed-off-by: Henrik Rydberg <rydberg at euromail.se>
---
updates/input/mouse/bcm5974.c | 117 ++++++++++++++---------------------------
1 files changed, 40 insertions(+), 77 deletions(-)
diff --git a/updates/input/mouse/bcm5974.c b/updates/input/mouse/bcm5974.c
index c43fc0c..6bd21fb 100644
--- a/updates/input/mouse/bcm5974.c
+++ b/updates/input/mouse/bcm5974.c
@@ -157,7 +157,6 @@ struct atp {
struct bt_data *bt_data; /* button transferred data */
struct urb *tp_urb; /* trackpad usb request block */
struct tp_data *tp_data; /* trackpad transferred data */
- unsigned tp_valid; /* trackpad sensors valid */
};
/* logical dimensions */
@@ -283,10 +282,9 @@ static int report_tp_state(struct atp *dev, int size)
#define ATP_WELLSPRING_MODE_WRITE_REQUEST_ID 9
#define ATP_WELLSPRING_MODE_REQUEST_VALUE 0x300
#define ATP_WELLSPRING_MODE_REQUEST_INDEX 0
-#define ATP_WELLSPRING_MODE_VENDOR_VALUE_1 0x01
-#define ATP_WELLSPRING_MODE_VENDOR_VALUE_2 0x05
+#define ATP_WELLSPRING_MODE_VENDOR_VALUE 0x01
-static int atp_wellspring_init(struct atp *dev)
+static int atp_wellspring_mode(struct atp *dev)
{
char *data = kmalloc(8, GFP_KERNEL);
int error = 0, size;
@@ -297,24 +295,6 @@ static int atp_wellspring_init(struct atp *dev)
goto error;
}
- /* reset button endpoint */
- if (usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
- USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
- 0, dev->cfg.bt_ep, NULL, 0, 5000)) {
- err("bcm5974: could not reset button endpoint");
- error = -EIO;
- goto error;
- }
-
- /* reset trackpad endpoint */
- if (usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
- USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
- 0, dev->cfg.tp_ep, NULL, 0, 5000)) {
- err("bcm5974: could not reset trackpad endpoint");
- error = -EIO;
- goto error;
- }
-
/* read configuration */
size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
ATP_WELLSPRING_MODE_READ_REQUEST_ID,
@@ -329,8 +309,7 @@ static int atp_wellspring_init(struct atp *dev)
}
/* apply the mode switch */
- data[0] = ATP_WELLSPRING_MODE_VENDOR_VALUE_1;
- data[1] = ATP_WELLSPRING_MODE_VENDOR_VALUE_2;
+ data[0] = ATP_WELLSPRING_MODE_VENDOR_VALUE;
/* write configuration */
size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
@@ -345,9 +324,7 @@ static int atp_wellspring_init(struct atp *dev)
goto error;
}
- dev->tp_valid = 0;
-
- printk(KERN_INFO "bcm5974: Wellspring mode initialized.\n");
+ dprintk(2, "bcm5974: switched to wellspring mode.\n");
kfree(data);
return 0;
@@ -409,11 +386,9 @@ static void irq_trackpad(struct urb *urb)
goto exit;
}
- /* first sample data ignored */
- if (!dev->tp_valid) {
- dev->tp_valid = 1;
+ /* control response ignored */
+ if (dev->tp_urb->actual_length == 2)
goto exit;
- }
if (report_tp_state(dev, dev->tp_urb->actual_length)) {
dprintk(1, "bcm5974: bad trackpad package, length: %d\n",
@@ -429,23 +404,45 @@ exit:
err("bcm5974: trackpad urb failed: %d", error);
}
+/*
+ * The Wellspring trackpad, like many recent Apple trackpads, share
+ * the usb device with the keyboard. Since keyboards are usually
+ * handled by the HID system, the device ends up being handled by two
+ * modules. Setting up the device therefore becomes slightly
+ * complicated. To enable multitouch features, a mode switch is
+ * required, which is usually applied via the control interface of the
+ * device. It can be argued where this switch should take place. In
+ * some drivers, like appletouch, the switch is made during
+ * probe. However, the hid module may also alter the state of the
+ * device, resulting in trackpad malfunction under certain
+ * circumstances. To get around this problem, there is at least one
+ * example that utilizes the USB_QUIRK_RESET_RESUME quirk in order to
+ * recieve a reset_resume request rather than the normal resume. Since
+ * the implementation of reset_resume is equal to mode switch plus
+ * open, it seems easier to always do the switch while opening the
+ * device.
+ */
static int atp_open(struct input_dev *input)
{
struct atp *dev = input_get_drvdata(input);
if (!dev->open) {
+ if (atp_wellspring_mode(dev)) {
+ dprintk(1, "bcm5974: mode switch failed\n");
+ goto error;
+ }
if (usb_submit_urb(dev->bt_urb, GFP_KERNEL))
goto error;
if (usb_submit_urb(dev->tp_urb, GFP_KERNEL))
- goto err_free_bt_urb;
+ goto err_kill_bt;
}
dev->open = 1;
dev->suspended = 0;
return 0;
-err_free_bt_urb:
- usb_free_urb(dev->bt_urb);
+err_kill_bt:
+ usb_kill_urb(dev->bt_urb);
error:
return -EIO;
}
@@ -486,12 +483,6 @@ static int atp_probe(struct usb_interface *iface,
dev->input = input_dev;
dev->cfg = *cfg;
- /* switch to raw sensor mode */
- if (atp_wellspring_init(dev)) {
- error = -EIO;
- goto err_free_devs;
- }
-
dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->bt_urb) {
error = -ENOMEM;
@@ -631,57 +622,27 @@ static int atp_resume(struct usb_interface *iface)
return error;
}
-static int atp_reset_resume(struct usb_interface *iface)
-{
- struct atp *dev = usb_get_intfdata(iface);
-
- if (dev && atp_wellspring_init(dev))
- printk(KERN_INFO "bcm5974: warning: reset failed\n");
-
- return atp_resume(iface);
-}
-
-static int atp_pre_reset(struct usb_interface *iface)
-{
- return atp_suspend(iface, PMSG_ON);
-}
-
-static int atp_post_reset(struct usb_interface *iface)
-{
- return atp_reset_resume(iface);
-}
-
static struct usb_driver atp_driver = {
.name = "bcm5974",
.probe = atp_probe,
.disconnect = atp_disconnect,
.suspend = atp_suspend,
.resume = atp_resume,
- .reset_resume = atp_reset_resume,
- .pre_reset = atp_pre_reset,
- .post_reset = atp_post_reset,
+ .reset_resume = atp_resume,
.id_table = atp_table,
};
-#define USB_VENDOR_ID_APPLE 0x05ac
-#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223
-#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224
-#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225
-#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
-#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
-#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
-
static const struct hid_blacklist {
__u16 idVendor;
__u16 idProduct;
__u32 quirks;
} hid_blacklist[] = {
- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE},
- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE},
- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE},
- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE },
- { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+ { APPLE_VENDOR_ID, ATP_WELLSPRING_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
+ { APPLE_VENDOR_ID, ATP_WELLSPRING_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE},
+ { APPLE_VENDOR_ID, ATP_WELLSPRING_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE},
+ { APPLE_VENDOR_ID, ATP_WELLSPRING2_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE},
+ { APPLE_VENDOR_ID, ATP_WELLSPRING2_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE },
+ { APPLE_VENDOR_ID, ATP_WELLSPRING2_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
{0,0,0}
};
@@ -689,6 +650,7 @@ static int __init atp_update_quirks(void)
{
struct hid_blacklist *bp;
int result=0;
+#if 0
for (bp=hid_blacklist; bp->quirks; bp++)
{
result = usbhid_modify_dquirk(bp->idVendor,bp->idProduct,bp->quirks);
@@ -698,6 +660,7 @@ static int __init atp_update_quirks(void)
break;
}
}
+#endif
return result;
}
--
1.5.4.3
More information about the kernel-team
mailing list