aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/bcm5974.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2009-04-27 14:52:42 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-04-28 12:35:03 -0400
commit9894cf0ff5e9ccda60d8d0e2d37bd61539b08826 (patch)
tree7768a2d0372437dac846bba471324b4357b55f5f /drivers/input/mouse/bcm5974.c
parent0385c5ee3ca96bfe244610bf459abf66682ff202 (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.c47
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 */
100struct tp_header { 100enum 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 */
107struct tp_finger { 108struct 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 */
123struct 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 */
129struct bcm5974_param { 128struct 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)
276static int report_tp_state(struct bcm5974 *dev, int size) 277static 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