summaryrefslogtreecommitdiff
path: root/usr/src/dkms_source_tree/bcm5974.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/dkms_source_tree/bcm5974.c')
-rw-r--r--usr/src/dkms_source_tree/bcm5974.c119
1 files changed, 79 insertions, 40 deletions
diff --git a/usr/src/dkms_source_tree/bcm5974.c b/usr/src/dkms_source_tree/bcm5974.c
index ef2ffab..b89879b 100644
--- a/usr/src/dkms_source_tree/bcm5974.c
+++ b/usr/src/dkms_source_tree/bcm5974.c
@@ -43,13 +43,6 @@
43 43
44#define USB_VENDOR_ID_APPLE 0x05ac 44#define USB_VENDOR_ID_APPLE 0x05ac
45 45
46#ifndef BTN_TOOL_PRESS
47#define BTN_TOOL_PRESS 0x148
48#endif
49#ifndef BTN_TOOL_QUADTAP
50#define BTN_TOOL_QUADTAP 0x14f
51#endif
52
53/* MacbookAir, aka wellspring */ 46/* MacbookAir, aka wellspring */
54#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223 47#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223
55#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224 48#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224
@@ -117,17 +110,17 @@ enum tp_type {
117 TYPE2 /* button integrated in trackpad */ 110 TYPE2 /* button integrated in trackpad */
118}; 111};
119 112
120/* trackpad finger data offsets */ 113/* trackpad finger data offsets, le16-aligned */
121#define FINGER_TYPE1 26 114#define FINGER_TYPE1 (13 * sizeof(__le16))
122#define FINGER_TYPE2 30 115#define FINGER_TYPE2 (15 * sizeof(__le16))
123 116
124/* trackpad button data offsets */ 117/* trackpad button data offsets */
125#define BUTTON_TYPE2 15 118#define BUTTON_TYPE2 15
126 119
127/* integrated button capability by configuration */ 120/* list of device capability bits */
128#define HAS_INTEGRATED_BUTTON(c) (c->tp_type == TYPE2) 121#define HAS_INTEGRATED_BUTTON 1
129 122
130/* trackpad finger structure */ 123/* trackpad finger structure, le16-aligned */
131struct tp_finger { 124struct tp_finger {
132 __le16 origin; /* zero when switching track finger */ 125 __le16 origin; /* zero when switching track finger */
133 __le16 abs_x; /* absolute x coodinate */ 126 __le16 abs_x; /* absolute x coodinate */
@@ -141,11 +134,12 @@ struct tp_finger {
141 __le16 force_minor; /* trackpad force, minor axis? */ 134 __le16 force_minor; /* trackpad force, minor axis? */
142 __le16 unused[3]; /* zeros */ 135 __le16 unused[3]; /* zeros */
143 __le16 multi; /* one finger: varies, more fingers: constant */ 136 __le16 multi; /* one finger: varies, more fingers: constant */
144}; 137} __attribute__((packed,aligned(2)));
145 138
146/* trackpad finger data size, empirically at least ten fingers */ 139/* trackpad finger data size, empirically at least ten fingers */
147#define SIZEOF_FINGER sizeof(struct tp_finger) 140#define SIZEOF_FINGER sizeof(struct tp_finger)
148#define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER) 141#define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER)
142#define MAX_FINGER_ORIENTATION 16384
149 143
150/* device-specific parameters */ 144/* device-specific parameters */
151struct bcm5974_param { 145struct bcm5974_param {
@@ -158,6 +152,7 @@ struct bcm5974_param {
158/* device-specific configuration */ 152/* device-specific configuration */
159struct bcm5974_config { 153struct bcm5974_config {
160 int ansi, iso, jis; /* the product id of this device */ 154 int ansi, iso, jis; /* the product id of this device */
155 int caps; /* device capability bitmask */
161 int bt_ep; /* the endpoint of the button interface */ 156 int bt_ep; /* the endpoint of the button interface */
162 int bt_datalen; /* data length of the button interface */ 157 int bt_datalen; /* data length of the button interface */
163 int tp_ep; /* the endpoint of the trackpad interface */ 158 int tp_ep; /* the endpoint of the trackpad interface */
@@ -207,6 +202,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
207 USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, 202 USB_DEVICE_ID_APPLE_WELLSPRING_ANSI,
208 USB_DEVICE_ID_APPLE_WELLSPRING_ISO, 203 USB_DEVICE_ID_APPLE_WELLSPRING_ISO,
209 USB_DEVICE_ID_APPLE_WELLSPRING_JIS, 204 USB_DEVICE_ID_APPLE_WELLSPRING_JIS,
205 0,
210 0x84, sizeof(struct bt_data), 206 0x84, sizeof(struct bt_data),
211 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, 207 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS,
212 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, 208 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
@@ -218,6 +214,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
218 USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, 214 USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI,
219 USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, 215 USB_DEVICE_ID_APPLE_WELLSPRING2_ISO,
220 USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, 216 USB_DEVICE_ID_APPLE_WELLSPRING2_JIS,
217 0,
221 0x84, sizeof(struct bt_data), 218 0x84, sizeof(struct bt_data),
222 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, 219 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS,
223 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, 220 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
@@ -229,6 +226,7 @@ static const struct bcm5974_config bcm5974_config_table[] = {
229 USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI, 226 USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI,
230 USB_DEVICE_ID_APPLE_WELLSPRING3_ISO, 227 USB_DEVICE_ID_APPLE_WELLSPRING3_ISO,
231 USB_DEVICE_ID_APPLE_WELLSPRING3_JIS, 228 USB_DEVICE_ID_APPLE_WELLSPRING3_JIS,
229 HAS_INTEGRATED_BUTTON,
232 0x84, sizeof(struct bt_data), 230 0x84, sizeof(struct bt_data),
233 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 231 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
234 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, 232 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 },
@@ -269,8 +267,7 @@ static inline int int2bound(const struct bcm5974_param *p, int x)
269{ 267{
270 int s = int2scale(p, x); 268 int s = int2scale(p, x);
271 269
272 //return clamp_val(s, 0, p->dim - 1); 270 return clamp_val(s, 0, p->dim - 1);
273 return s < 0 ? 0 : s >= p->dim ? p->dim - 1 : s;
274} 271}
275 272
276/* setup which logical events to report */ 273/* setup which logical events to report */
@@ -288,14 +285,32 @@ static void setup_events_to_report(struct input_dev *input_dev,
288 input_set_abs_params(input_dev, ABS_Y, 285 input_set_abs_params(input_dev, ABS_Y,
289 0, cfg->y.dim, cfg->y.fuzz, 0); 286 0, cfg->y.dim, cfg->y.fuzz, 0);
290 287
288 /* finger touch area */
289 input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
290 cfg->w.devmin, cfg->w.devmax, 0, 0);
291 input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR,
292 cfg->w.devmin, cfg->w.devmax, 0, 0);
293 /* finger approach area */
294 input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR,
295 cfg->w.devmin, cfg->w.devmax, 0, 0);
296 input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR,
297 cfg->w.devmin, cfg->w.devmax, 0, 0);
298 /* finger orientation */
299 input_set_abs_params(input_dev, ABS_MT_ORIENTATION,
300 -MAX_FINGER_ORIENTATION,
301 MAX_FINGER_ORIENTATION, 0, 0);
302 /* finger position */
303 input_set_abs_params(input_dev, ABS_MT_POSITION_X,
304 cfg->x.devmin, cfg->x.devmax, 0, 0);
305 input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
306 cfg->y.devmin, cfg->y.devmax, 0, 0);
307
291 __set_bit(EV_KEY, input_dev->evbit); 308 __set_bit(EV_KEY, input_dev->evbit);
292 __set_bit(BTN_TOUCH, input_dev->keybit); 309 __set_bit(BTN_TOUCH, input_dev->keybit);
293 __set_bit(BTN_TOOL_FINGER, input_dev->keybit); 310 __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
294 __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); 311 __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
295 __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); 312 __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
296 __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); 313 __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
297 if (HAS_INTEGRATED_BUTTON(cfg))
298 __set_bit(BTN_TOOL_PRESS, input_dev->keybit);
299 __set_bit(BTN_LEFT, input_dev->keybit); 314 __set_bit(BTN_LEFT, input_dev->keybit);
300} 315}
301 316
@@ -316,32 +331,55 @@ static int report_bt_state(struct bcm5974 *dev, int size)
316 return 0; 331 return 0;
317} 332}
318 333
334static void report_finger_data(struct input_dev *input,
335 const struct bcm5974_config *cfg,
336 const struct tp_finger *f)
337{
338 input_report_abs(input, ABS_MT_TOUCH_MAJOR, raw2int(f->force_major));
339 input_report_abs(input, ABS_MT_TOUCH_MINOR, raw2int(f->force_minor));
340 input_report_abs(input, ABS_MT_WIDTH_MAJOR, raw2int(f->size_major));
341 input_report_abs(input, ABS_MT_WIDTH_MINOR, raw2int(f->size_minor));
342 input_report_abs(input, ABS_MT_ORIENTATION,
343 MAX_FINGER_ORIENTATION - raw2int(f->orientation));
344 input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x));
345 input_report_abs(input, ABS_MT_POSITION_Y,
346 cfg->y.devmin + cfg->y.devmax - raw2int(f->abs_y));
347 input_mt_sync(input);
348}
349
319/* report trackpad data as logical trackpad state */ 350/* report trackpad data as logical trackpad state */
320static int report_tp_state(struct bcm5974 *dev, int size) 351static int report_tp_state(struct bcm5974 *dev, int size)
321{ 352{
322 const struct bcm5974_config *c = &dev->cfg; 353 const struct bcm5974_config *c = &dev->cfg;
323 const struct tp_finger *f; 354 const struct tp_finger *f;
324 struct input_dev *input = dev->input; 355 struct input_dev *input = dev->input;
325 int raw_p, raw_w, raw_x, raw_y, raw_n; 356 int raw_p, raw_w, raw_x, raw_y, raw_n, i;
326 int ptest = 0, origin = 0, ibt = 0, nmin = 0, nmax = 0; 357 int ptest, origin, ibt = 0, nmin = 0, nmax = 0;
327 int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; 358 int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
328 359
329 if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) 360 if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0)
330 return -EIO; 361 return -EIO;
331 362
363 /* finger data, le16-aligned */
332 f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); 364 f = (const struct tp_finger *)(dev->tp_data + c->tp_offset);
333 raw_n = (size - c->tp_offset) / SIZEOF_FINGER; 365 raw_n = (size - c->tp_offset) / SIZEOF_FINGER;
334 366
335 /* always track the first finger; when detached, start over */ 367 /* always track the first finger; when detached, start over */
336 if (raw_n) { 368 if (raw_n) {
369
370 /* report raw trackpad data */
371 for (i = 0; i < raw_n; i++)
372 report_finger_data(input, c, &f[i]);
373
337 raw_p = raw2int(f->force_major); 374 raw_p = raw2int(f->force_major);
338 raw_w = raw2int(f->size_major); 375 raw_w = raw2int(f->size_major);
339 raw_x = raw2int(f->abs_x); 376 raw_x = raw2int(f->abs_x);
340 raw_y = raw2int(f->abs_y); 377 raw_y = raw2int(f->abs_y);
341 378
342 dprintk(9, 379 dprintk(9,
343 "bcm5974: raw: p: %+05d w: %+05d x: %+05d y: %+05d " 380 "bcm5974: "
344 "n: %d\n", raw_p, raw_w, raw_x, raw_y, raw_n); 381 "raw: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n",
382 raw_p, raw_w, raw_x, raw_y, raw_n);
345 383
346 ptest = int2bound(&c->p, raw_p); 384 ptest = int2bound(&c->p, raw_p);
347 origin = raw2int(f->origin); 385 origin = raw2int(f->origin);
@@ -349,21 +387,22 @@ static int report_tp_state(struct bcm5974 *dev, int size)
349 /* set the integrated button if applicable */ 387 /* set the integrated button if applicable */
350 if (c->tp_type == TYPE2) 388 if (c->tp_type == TYPE2)
351 ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); 389 ibt = raw2int(dev->tp_data[BUTTON_TYPE2]);
352 }
353 390
354 /* while tracking finger still valid, count all fingers */ 391 /* while tracking finger still valid, count all fingers */
355 if (ptest > PRESSURE_LOW && origin) { 392 if (ptest > PRESSURE_LOW && origin) {
356 abs_p = ptest; 393 abs_p = ptest;
357 abs_w = int2bound(&c->w, raw_w); 394 abs_w = int2bound(&c->w, raw_w);
358 abs_x = int2bound(&c->x, raw_x - c->x.devmin); 395 abs_x = int2bound(&c->x, raw_x - c->x.devmin);
359 abs_y = int2bound(&c->y, c->y.devmax - raw_y); 396 abs_y = int2bound(&c->y, c->y.devmax - raw_y);
360 while (raw_n--) { 397 while (raw_n--) {
361 ptest = int2bound(&c->p, raw2int(f->force_major)); 398 ptest = int2bound(&c->p,
362 if (ptest > PRESSURE_LOW) 399 raw2int(f->force_major));
363 nmax++; 400 if (ptest > PRESSURE_LOW)
364 if (ptest > PRESSURE_HIGH) 401 nmax++;
365 nmin++; 402 if (ptest > PRESSURE_HIGH)
366 f++; 403 nmin++;
404 f++;
405 }
367 } 406 }
368 } 407 }
369 408
@@ -392,10 +431,9 @@ static int report_tp_state(struct bcm5974 *dev, int size)
392 431
393 } 432 }
394 433
395 if (HAS_INTEGRATED_BUTTON(c)) { 434 /* type 2 reports button events via ibt only */
396 input_report_key(input, BTN_TOOL_PRESS, ibt); 435 if (c->tp_type == TYPE2)
397 input_report_key(input, BTN_LEFT, ibt); 436 input_report_key(input, BTN_LEFT, ibt);
398 }
399 437
400 input_sync(input); 438 input_sync(input);
401 439
@@ -706,6 +744,8 @@ static int bcm5974_probe(struct usb_interface *iface,
706 input_dev->name = "bcm5974"; 744 input_dev->name = "bcm5974";
707 input_dev->phys = dev->phys; 745 input_dev->phys = dev->phys;
708 usb_to_input_id(dev->udev, &input_dev->id); 746 usb_to_input_id(dev->udev, &input_dev->id);
747 /* report driver capabilities via the version field */
748 input_dev->id.version = cfg->caps;
709 input_dev->dev.parent = &iface->dev; 749 input_dev->dev.parent = &iface->dev;
710 750
711 input_set_drvdata(input_dev, dev); 751 input_set_drvdata(input_dev, dev);
@@ -763,7 +803,6 @@ static struct usb_driver bcm5974_driver = {
763 .disconnect = bcm5974_disconnect, 803 .disconnect = bcm5974_disconnect,
764 .suspend = bcm5974_suspend, 804 .suspend = bcm5974_suspend,
765 .resume = bcm5974_resume, 805 .resume = bcm5974_resume,
766 .reset_resume = bcm5974_resume,
767 .id_table = bcm5974_table, 806 .id_table = bcm5974_table,
768 .supports_autosuspend = 1, 807 .supports_autosuspend = 1,
769}; 808};