Sharedwww / macbook / appletouch.patchOpen in CoCalc
Author: William A. Stein
1
2
3
--- drivers/usb/input/appletouch.c.ori2006-04-17 13:03:58.000000000 +0200
4
+++ drivers/usb/input/appletouch.c2006-04-19 23:20:17.000000000 +0200
5
@@ -1,5 +1,5 @@
6
/*
7
- * Apple USB Touchpad (for post-February 2005 PowerBooks) driver
8
+ * Apple USB Touchpad (for post-February 2005 PowerBooks and MacBooks) driver
9
*
10
* Copyright (C) 2001-2004 Greg Kroah-Hartman ([email protected])
11
* Copyright (C) 2005 Johannes Berg ([email protected])
12
@@ -7,6 +7,7 @@
13
* Copyright (C) 2005 Frank Arnold ([email protected])
14
* Copyright (C) 2005 Peter Osterlund ([email protected])
15
* Copyright (C) 2005 Michael Hanselmann ([email protected])
16
+ * Copyright (C) 2006 Nicolas Boichat ([email protected])
17
*
18
* Thanks to Alex Harper <[email protected]> for his inputs.
19
*
20
@@ -44,6 +45,11 @@
21
#define GEYSER_ISO_PRODUCT_ID0x0215
22
#define GEYSER_JIS_PRODUCT_ID0x0216
23
24
+/* MacBook devices */
25
+#define GEYSER3_ANSI_PRODUCT_ID0x0217
26
+#define GEYSER3_ISO_PRODUCT_ID0x0218
27
+#define GEYSER3_JIS_PRODUCT_ID0x0219
28
+
29
#define ATP_DEVICE(prod)\
30
.match_flags = USB_DEVICE_ID_MATCH_DEVICE |\
31
USB_DEVICE_ID_MATCH_INT_CLASS |\
32
@@ -65,6 +71,10 @@ static struct usb_device_id atp_table []
33
{ ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) },
34
{ ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) },
35
36
+{ ATP_DEVICE(GEYSER3_ANSI_PRODUCT_ID) },
37
+{ ATP_DEVICE(GEYSER3_ISO_PRODUCT_ID) },
38
+{ ATP_DEVICE(GEYSER3_JIS_PRODUCT_ID) },
39
+
40
/* Terminating entry */
41
{ }
42
};
43
@@ -101,6 +111,13 @@ MODULE_DEVICE_TABLE (usb, atp_table);
44
*/
45
#define ATP_THRESHOLD 5
46
47
+/* MacBook Pro (Geyser 3) initialization constants */
48
+#define ATP_GEYSER3_MODE_READ_REQUEST_ID 1
49
+#define ATP_GEYSER3_MODE_WRITE_REQUEST_ID 9
50
+#define ATP_GEYSER3_MODE_REQUEST_VALUE 0x300
51
+#define ATP_GEYSER3_MODE_REQUEST_INDEX 0
52
+#define ATP_GEYSER3_MODE_VENDOR_VALUE 0x04
53
+
54
/* Structure to hold all of our device specific stuff */
55
struct atp {
56
charphys[64];
57
@@ -147,13 +164,22 @@ MODULE_PARM_DESC(debug, "Activate debugg
58
/* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */
59
static inline int atp_is_geyser_2(struct atp *dev)
60
{
61
-int16_t productId = le16_to_cpu(dev->udev->descriptor.idProduct);
62
+u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
63
64
return (productId == GEYSER_ANSI_PRODUCT_ID) ||
65
(productId == GEYSER_ISO_PRODUCT_ID) ||
66
(productId == GEYSER_JIS_PRODUCT_ID);
67
}
68
69
+static inline int atp_is_geyser_3(struct atp *dev)
70
+{
71
+u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
72
+
73
+return (productId == GEYSER3_ANSI_PRODUCT_ID) ||
74
+(productId == GEYSER3_ISO_PRODUCT_ID) ||
75
+(productId == GEYSER3_JIS_PRODUCT_ID);
76
+}
77
+
78
static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
79
int *z, int *fingers)
80
{
81
@@ -219,12 +245,33 @@ static void atp_complete(struct urb* urb
82
83
/* drop incomplete datasets */
84
if (dev->urb->actual_length != dev->datalen) {
85
-dprintk("appletouch: incomplete data package.\n");
86
+dprintk("appletouch: incomplete data package"
87
+" (first byte: %d, length: %d).\n",
88
+dev->data[0], dev->urb->actual_length);
89
goto exit;
90
}
91
92
/* reorder the sensors values */
93
-if (atp_is_geyser_2(dev)) {
94
+if (atp_is_geyser_3(dev)) {
95
+memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
96
+
97
+/*
98
+ * The values are laid out like this:
99
+ * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ...
100
+ * '-' is an unused value.
101
+ */
102
+
103
+/* read X values */
104
+for (i = 0, j = 19; i < 20; i += 2, j += 3) {
105
+dev->xy_cur[i] = dev->data[j + 1];
106
+dev->xy_cur[i + 1] = dev->data[j + 2];
107
+}
108
+/* read Y values */
109
+for (i = 0, j = 1; i < 9; i += 2, j += 3) {
110
+dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];
111
+dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];
112
+}
113
+} else if (atp_is_geyser_2(dev)) {
114
memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
115
116
/*
117
@@ -267,6 +314,9 @@ static void atp_complete(struct urb* urb
118
dev->x_old = dev->y_old = -1;
119
memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
120
121
+if (atp_is_geyser_3(dev)) /* No 17" Macbooks (yet) */
122
+goto exit;
123
+
124
/* 17" Powerbooks have extra X sensors */
125
for (i = (atp_is_geyser_2(dev)?15:16); i < ATP_XSENSORS; i++) {
126
if (!dev->xy_cur[i]) continue;
127
@@ -414,7 +464,50 @@ static int atp_probe(struct usb_interfac
128
dev->udev = udev;
129
dev->input = input_dev;
130
dev->overflowwarn = 0;
131
-dev->datalen = (atp_is_geyser_2(dev)?64:81);
132
+if (atp_is_geyser_3(dev))
133
+dev->datalen = 64;
134
+else if (atp_is_geyser_2(dev))
135
+dev->datalen = 64;
136
+else
137
+dev->datalen = 81;
138
+
139
+if (atp_is_geyser_3(dev)) {
140
+/*
141
+ * By default Geyser 3 device sends standard USB HID mouse
142
+ * packets (Report ID 2). This code changes device mode, so it
143
+ * sends raw sensor reports (Report ID 5).
144
+ */
145
+char data[8];
146
+int size;
147
+
148
+size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
149
+ATP_GEYSER3_MODE_READ_REQUEST_ID,
150
+USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
151
+ATP_GEYSER3_MODE_REQUEST_VALUE,
152
+ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);
153
+
154
+if (size != 8) {
155
+err("Could not do mode read request from device"
156
+" (Geyser 3 mode)");
157
+goto err_free_devs;
158
+}
159
+
160
+/* Apply the mode switch */
161
+data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE;
162
+
163
+size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
164
+ATP_GEYSER3_MODE_WRITE_REQUEST_ID,
165
+USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
166
+ATP_GEYSER3_MODE_REQUEST_VALUE,
167
+ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);
168
+
169
+if (size != 8) {
170
+err("Could not do mode write request to device"
171
+" (Geyser 3 mode)");
172
+goto err_free_devs;
173
+}
174
+printk("appletouch Geyser 3 inited.\n");
175
+}
176
177
dev->urb = usb_alloc_urb(0, GFP_KERNEL);
178
if (!dev->urb) {
179
@@ -447,9 +540,17 @@ static int atp_probe(struct usb_interfac
180
181
set_bit(EV_ABS, input_dev->evbit);
182
183
-if (atp_is_geyser_2(dev)) {
184
+if (atp_is_geyser_3(dev)) {
185
+/*
186
+ * MacBook have 20 X sensors, 10 Y sensors
187
+ */
188
+input_set_abs_params(input_dev, ABS_X, 0,
189
+ ((20 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0);
190
+input_set_abs_params(input_dev, ABS_Y, 0,
191
+ ((10 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0);
192
+} else if (atp_is_geyser_2(dev)) {
193
/*
194
* Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected
195
* later.
196
197
198
199