diff options
author | Henrik Rydberg <rydberg@euromail.se> | 2009-04-27 14:52:42 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-04-28 12:35:03 -0400 |
commit | 9894cf0ff5e9ccda60d8d0e2d37bd61539b08826 (patch) | |
tree | 7768a2d0372437dac846bba471324b4357b55f5f /drivers/input/mouse/bcm5974.c | |
parent | 0385c5ee3ca96bfe244610bf459abf66682ff202 (diff) |
Input: bcm5974 - prepare for a new trackpad header type
The new unibody Macbooks are equipped with an integrated button and
trackpad. The package header of the trackpad interface has changed to
also contain information about the integrated button. This patch
performs the necessary preparations to allow for the new package
header.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/mouse/bcm5974.c')
-rw-r--r-- | drivers/input/mouse/bcm5974.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 2998a6ac9ae4..bda873393b0d 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -96,14 +96,15 @@ struct bt_data { | |||
96 | u8 rel_y; /* relative y coordinate */ | 96 | u8 rel_y; /* relative y coordinate */ |
97 | }; | 97 | }; |
98 | 98 | ||
99 | /* trackpad header structure */ | 99 | /* trackpad header types */ |
100 | struct tp_header { | 100 | enum tp_type { |
101 | u8 unknown1[16]; /* constants, timers, etc */ | 101 | TYPE1 /* plain trackpad */ |
102 | u8 fingers; /* number of fingers on trackpad */ | ||
103 | u8 unknown2[9]; /* constants, timers, etc */ | ||
104 | }; | 102 | }; |
105 | 103 | ||
106 | /* trackpad finger structure */ | 104 | /* trackpad finger data offsets, le16-aligned */ |
105 | #define FINGER_TYPE1 (13 * sizeof(__le16)) | ||
106 | |||
107 | /* trackpad finger structure, le16-aligned */ | ||
107 | struct tp_finger { | 108 | struct tp_finger { |
108 | __le16 origin; /* zero when switching track finger */ | 109 | __le16 origin; /* zero when switching track finger */ |
109 | __le16 abs_x; /* absolute x coodinate */ | 110 | __le16 abs_x; /* absolute x coodinate */ |
@@ -117,13 +118,11 @@ struct tp_finger { | |||
117 | __le16 force_minor; /* trackpad force, minor axis? */ | 118 | __le16 force_minor; /* trackpad force, minor axis? */ |
118 | __le16 unused[3]; /* zeros */ | 119 | __le16 unused[3]; /* zeros */ |
119 | __le16 multi; /* one finger: varies, more fingers: constant */ | 120 | __le16 multi; /* one finger: varies, more fingers: constant */ |
120 | }; | 121 | } __attribute__((packed,aligned(2))); |
121 | 122 | ||
122 | /* trackpad data structure, empirically at least ten fingers */ | 123 | /* trackpad finger data size, empirically at least ten fingers */ |
123 | struct tp_data { | 124 | #define SIZEOF_FINGER sizeof(struct tp_finger) |
124 | struct tp_header header; | 125 | #define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER) |
125 | struct tp_finger finger[16]; | ||
126 | }; | ||
127 | 126 | ||
128 | /* device-specific parameters */ | 127 | /* device-specific parameters */ |
129 | struct bcm5974_param { | 128 | struct bcm5974_param { |
@@ -139,6 +138,8 @@ struct bcm5974_config { | |||
139 | int bt_ep; /* the endpoint of the button interface */ | 138 | int bt_ep; /* the endpoint of the button interface */ |
140 | int bt_datalen; /* data length of the button interface */ | 139 | int bt_datalen; /* data length of the button interface */ |
141 | int tp_ep; /* the endpoint of the trackpad interface */ | 140 | int tp_ep; /* the endpoint of the trackpad interface */ |
141 | enum tp_type tp_type; /* type of trackpad interface */ | ||
142 | int tp_offset; /* offset to trackpad finger data */ | ||
142 | int tp_datalen; /* data length of the trackpad interface */ | 143 | int tp_datalen; /* data length of the trackpad interface */ |
143 | struct bcm5974_param p; /* finger pressure limits */ | 144 | struct bcm5974_param p; /* finger pressure limits */ |
144 | struct bcm5974_param w; /* finger width limits */ | 145 | struct bcm5974_param w; /* finger width limits */ |
@@ -158,7 +159,7 @@ struct bcm5974 { | |||
158 | struct urb *bt_urb; /* button usb request block */ | 159 | struct urb *bt_urb; /* button usb request block */ |
159 | struct bt_data *bt_data; /* button transferred data */ | 160 | struct bt_data *bt_data; /* button transferred data */ |
160 | struct urb *tp_urb; /* trackpad usb request block */ | 161 | struct urb *tp_urb; /* trackpad usb request block */ |
161 | struct tp_data *tp_data; /* trackpad transferred data */ | 162 | u8 *tp_data; /* trackpad transferred data */ |
162 | int fingers; /* number of fingers on trackpad */ | 163 | int fingers; /* number of fingers on trackpad */ |
163 | }; | 164 | }; |
164 | 165 | ||
@@ -184,7 +185,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
184 | USB_DEVICE_ID_APPLE_WELLSPRING_ISO, | 185 | USB_DEVICE_ID_APPLE_WELLSPRING_ISO, |
185 | USB_DEVICE_ID_APPLE_WELLSPRING_JIS, | 186 | USB_DEVICE_ID_APPLE_WELLSPRING_JIS, |
186 | 0x84, sizeof(struct bt_data), | 187 | 0x84, sizeof(struct bt_data), |
187 | 0x81, sizeof(struct tp_data), | 188 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, |
188 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, | 189 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, |
189 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 190 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, |
190 | { DIM_X, DIM_X / SN_COORD, -4824, 5342 }, | 191 | { DIM_X, DIM_X / SN_COORD, -4824, 5342 }, |
@@ -195,7 +196,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
195 | USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, | 196 | USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, |
196 | USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, | 197 | USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, |
197 | 0x84, sizeof(struct bt_data), | 198 | 0x84, sizeof(struct bt_data), |
198 | 0x81, sizeof(struct tp_data), | 199 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, |
199 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, | 200 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, |
200 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 201 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, |
201 | { DIM_X, DIM_X / SN_COORD, -4824, 4824 }, | 202 | { DIM_X, DIM_X / SN_COORD, -4824, 4824 }, |
@@ -276,18 +277,21 @@ static int report_bt_state(struct bcm5974 *dev, int size) | |||
276 | static int report_tp_state(struct bcm5974 *dev, int size) | 277 | static int report_tp_state(struct bcm5974 *dev, int size) |
277 | { | 278 | { |
278 | const struct bcm5974_config *c = &dev->cfg; | 279 | const struct bcm5974_config *c = &dev->cfg; |
279 | const struct tp_finger *f = dev->tp_data->finger; | 280 | const struct tp_finger *f; |
280 | struct input_dev *input = dev->input; | 281 | struct input_dev *input = dev->input; |
281 | const int fingers = (size - 26) / 28; | 282 | int raw_p, raw_w, raw_x, raw_y, raw_n; |
282 | int raw_p, raw_w, raw_x, raw_y; | ||
283 | int ptest = 0, origin = 0, nmin = 0, nmax = 0; | 283 | int ptest = 0, origin = 0, nmin = 0, nmax = 0; |
284 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; | 284 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; |
285 | 285 | ||
286 | if (size < 26 || (size - 26) % 28 != 0) | 286 | if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) |
287 | return -EIO; | 287 | return -EIO; |
288 | 288 | ||
289 | /* finger data, le16-aligned */ | ||
290 | f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); | ||
291 | raw_n = (size - c->tp_offset) / SIZEOF_FINGER; | ||
292 | |||
289 | /* always track the first finger; when detached, start over */ | 293 | /* always track the first finger; when detached, start over */ |
290 | if (fingers) { | 294 | if (raw_n) { |
291 | raw_p = raw2int(f->force_major); | 295 | raw_p = raw2int(f->force_major); |
292 | raw_w = raw2int(f->size_major); | 296 | raw_w = raw2int(f->size_major); |
293 | raw_x = raw2int(f->abs_x); | 297 | raw_x = raw2int(f->abs_x); |
@@ -307,12 +311,13 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
307 | abs_w = int2bound(&c->w, raw_w); | 311 | abs_w = int2bound(&c->w, raw_w); |
308 | abs_x = int2bound(&c->x, raw_x - c->x.devmin); | 312 | abs_x = int2bound(&c->x, raw_x - c->x.devmin); |
309 | abs_y = int2bound(&c->y, c->y.devmax - raw_y); | 313 | abs_y = int2bound(&c->y, c->y.devmax - raw_y); |
310 | for (; f != dev->tp_data->finger + fingers; f++) { | 314 | while (raw_n--) { |
311 | ptest = int2bound(&c->p, raw2int(f->force_major)); | 315 | ptest = int2bound(&c->p, raw2int(f->force_major)); |
312 | if (ptest > PRESSURE_LOW) | 316 | if (ptest > PRESSURE_LOW) |
313 | nmax++; | 317 | nmax++; |
314 | if (ptest > PRESSURE_HIGH) | 318 | if (ptest > PRESSURE_HIGH) |
315 | nmin++; | 319 | nmin++; |
320 | f++; | ||
316 | } | 321 | } |
317 | } | 322 | } |
318 | 323 | ||