On Mon, 2007-07-16 at 10:32 +1000, Daniel M. Newman wrote:
> Using kernel 2.6.22 and the mactel-linux revision 133 patch set from svn
> on a Macbook Pro 15in, there seem to be a couple of peculiarities in the
> trackpad behaviour.
please try the attached kernel patch and make sure that you are using a
new X synaptics driver (e.g. 0.14.7~git20070517 )...
> 1. During boot-up, the appletouch module always loads normally.
> However, as X (using the fglrx driver 8.38.6) starts up I sometimes
> (about one time in five) get an error that the core pointer is
> unavailable. When this happens, the following shows up in syslog:
>
> kernel: BUG: scheduling while atomic: Xorg/0x00000001/2826
> kernel: [schedule+1267/2448] schedule+0x4f3/0x990
> kernel: [_spin_unlock+13/48] _spin_unlock+0xd/0x30
> kernel: [__wake_up_common+57/112] __wake_up_common+0x39/0x70
> kernel: [__wake_up+56/80] __wake_up+0x38/0x50
> kernel: [<f89d8f81>] irqmgr_wrap_shutdown+0xe1/0x150 [fglrx]
> kernel: [<f89c9f45>] firegl_takedown+0x625/0xc50 [fglrx]
> kernel: [proc_delete_inode+0/96] proc_delete_inode+0x0/0x60
> kernel: [<f89c900f>] firegl_release+0x12f/0x190 [fglrx]
> kernel: [<f89bd44f>] ip_firegl_release+0xf/0x20 [fglrx]
> kernel: [__fput+151/368] __fput+0x97/0x170
> kernel: [filp_close+73/128] filp_close+0x49/0x80
> kernel: [put_files_struct+156/192] put_files_struct+0x9c/0xc0
> kernel: [do_exit+314/2016] do_exit+0x13a/0x7e0
> kernel: [<f8a14be9>] IRQMGR_WorkerThreadRoutine+0x29/0x30 [fglrx]
> kernel: [<f89bab90>] kasThreadRoutineHelper+0x0/0x20 [fglrx]
> kernel: [<f89bab90>] kasThreadRoutineHelper+0x0/0x20 [fglrx]
> kernel: [<f89d8d2e>] IRQMGR_CallbackWrapper+0xe/0x20 [fglrx]
> kernel: [<f89bab90>] kasThreadRoutineHelper+0x0/0x20 [fglrx]
> kernel: [kernel_thread_helper+13/20] kernel_thread_helper+0xd/0x14
>
> Removing and re-inserting appletouch generally fixes this, although
> sometimes I have to do the remove and reinsert twice.
this sounds more like a bug in fglrx... but I've yet to see this to
happen...
> 2. I have my screen set to blank after a period of non-usage. When
> waking up after this happens, the trackpad cursor no longer follows
> finger movements reliably. Removing and re-inserting the appletouch
> module fixes this, but does not re-enable response to two- and three-
> finger taps. Restarting gdm fixes both problems.
that should be fixed by the patch.
> 3. Trackpad button presses sometimes do not generate an immediate
> response. However, if the trackpad button is pressed and no response
> happens, a small movement of the cursor will cause the response to
> occur. It seems that the button press input is being queued, but the
> queue is not checked until trackpad motion is detected. I thought this
> might be due to my xorg.conf settings, but these seem to be in
> accordance with the various recommendations (see below).
strange...
Please report back whether it still happens with the attached patch and
a newer synaptics xorg driver...
Thanks,
Soeren
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index e321526..0426054 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -155,6 +155,8 @@ struct atp {
int xy_acc[ATP_XSENSORS + ATP_YSENSORS];
int overflowwarn; /* overflow warning printed? */
int datalen; /* size of an USB urb transfer */
+ int idlecount; /* number of empty packets */
+ struct work_struct work;
};
#define dbg_dump(msg, tab) \
@@ -208,6 +210,64 @@ static inline int atp_is_geyser_3(struct atp *dev)
(productId == GEYSER4_JIS_PRODUCT_ID);
}
+/*
+ * By default Geyser 3 device sends standard USB HID mouse
+ * packets (Report ID 2). This code changes device mode, so it
+ * sends raw sensor reports (Report ID 5).
+ */
+static int atp_geyser3_init(struct usb_device *udev)
+{
+ char data[8];
+ int size;
+ int i;
+
+ size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ ATP_GEYSER3_MODE_READ_REQUEST_ID,
+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ ATP_GEYSER3_MODE_REQUEST_VALUE,
+ ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);
+
+
+ if (size != 8) {
+ printk("appletouch atp_geyser3_init READ error\n");
+ for (i=0; i<8; i++)
+ printk("appletouch[%d]: %d\n", i, (int) data[i]);
+
+ err("Could not do mode read request from device"
+ " (Geyser 3 mode)");
+ return -EIO;
+ }
+
+ /* Apply the mode switch */
+ data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE;
+
+ size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ ATP_GEYSER3_MODE_WRITE_REQUEST_ID,
+ USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ ATP_GEYSER3_MODE_REQUEST_VALUE,
+ ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);
+
+ if (size != 8) {
+ printk("appletouch atp_geyser3_init WRITE error\n");
+ for (i=0; i<8; i++)
+ printk("appletouch[%d]: %d\n", i, (int) data[i]);
+ err("Could not do mode write request to device"
+ " (Geyser 3 mode)");
+ return -EIO;
+ }
+ return 0;
+}
+
+/* Reinitialise the device if it's a geyser 3 */
+static void atp_reinit(struct work_struct *work)
+{
+ struct atp *dev = container_of(work, struct atp, work);
+ struct usb_device *udev = dev->udev;
+
+ dev->idlecount = 0;
+ atp_geyser3_init(udev);
+}
+
static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
int *z, int *fingers)
{
@@ -418,6 +478,8 @@ static void atp_complete(struct urb* urb)
y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,
ATP_YFACT, &y_z, &y_f);
+ input_report_key(dev->input, BTN_LEFT, dev->data[dev->datalen-1] & 1);
+
if (x && y) {
if (dev->x_old != -1) {
x = (dev->x_old * 3 + x) >> 2;
@@ -449,10 +511,19 @@ static void atp_complete(struct urb* urb)
/* reset the accumulator on release */
memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
- }
- input_report_key(dev->input, BTN_LEFT,
- !!dev->data[dev->datalen - 1]);
+ /* Geyser 3 will continue to send packets continually after
+ the first touch unless reinitialised. Do so if it's been
+ idle for a while in order to avoid waking the kernel up
+ several hundred times a second */
+ if (atp_is_geyser_3(dev)) {
+ dev->idlecount++;
+ if (dev->idlecount == 10) {
+ dev->valid=0;
+ schedule_work (&dev->work);
+ }
+ }
+ }
input_sync(dev->input);
@@ -528,40 +599,10 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
dev->datalen = 81;
if (atp_is_geyser_3(dev)) {
- /*
- * By default Geyser 3 device sends standard USB HID mouse
- * packets (Report ID 2). This code changes device mode, so it
- * sends raw sensor reports (Report ID 5).
- */
- char data[8];
- int size;
-
- size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- ATP_GEYSER3_MODE_READ_REQUEST_ID,
- USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- ATP_GEYSER3_MODE_REQUEST_VALUE,
- ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);
-
- if (size != 8) {
- err("Could not do mode read request from device"
- " (Geyser 3 mode)");
+ /* switch to raw sensor mode */
+ if (atp_geyser3_init(udev))
goto err_free_devs;
- }
-
- /* Apply the mode switch */
- data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE;
- size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- ATP_GEYSER3_MODE_WRITE_REQUEST_ID,
- USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
- ATP_GEYSER3_MODE_REQUEST_VALUE,
- ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);
-
- if (size != 8) {
- err("Could not do mode write request to device"
- " (Geyser 3 mode)");
- goto err_free_devs;
- }
printk("appletouch Geyser 3 inited.\n");
}
@@ -636,6 +677,8 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
/* save our data pointer in this interface device */
usb_set_intfdata(iface, dev);
+ INIT_WORK(&dev->work, atp_reinit);
+
return 0;
err_free_buffer:
@@ -656,6 +699,7 @@ static void atp_disconnect(struct usb_interface *iface)
usb_set_intfdata(iface, NULL);
if (dev) {
+ cancel_work_sync(&dev->work);
usb_kill_urb(dev->urb);
input_unregister_device(dev->input);
usb_buffer_free(dev->udev, dev->datalen,
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Mactel-linux-devel mailing list
Mactel-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mactel-linux-devel