diff options
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/dkms_source_tree/bcm5974.c | 119 | ||||
| -rw-r--r-- | usr/src/dkms_source_tree/dkms.conf | 2 |
2 files changed, 80 insertions, 41 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 */ |
| 131 | struct tp_finger { | 124 | struct 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 */ |
| 151 | struct bcm5974_param { | 145 | struct bcm5974_param { |
| @@ -158,6 +152,7 @@ struct bcm5974_param { | |||
| 158 | /* device-specific configuration */ | 152 | /* device-specific configuration */ |
| 159 | struct bcm5974_config { | 153 | struct 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 | ||
| 334 | static 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 */ |
| 320 | static int report_tp_state(struct bcm5974 *dev, int size) | 351 | static 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 | }; |
diff --git a/usr/src/dkms_source_tree/dkms.conf b/usr/src/dkms_source_tree/dkms.conf index bcec41d..bb1ed5b 100644 --- a/usr/src/dkms_source_tree/dkms.conf +++ b/usr/src/dkms_source_tree/dkms.conf | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | NAME=bcm5974 | 1 | NAME=bcm5974 |
| 2 | VERSION=1.1.3 | 2 | VERSION=1.1.4 |
| 3 | PACKAGE_NAME="$NAME" | 3 | PACKAGE_NAME="$NAME" |
| 4 | PACKAGE_VERSION="$VERSION" | 4 | PACKAGE_VERSION="$VERSION" |
| 5 | MAKE[0]="make -C ${kernel_source_dir} | 5 | MAKE[0]="make -C ${kernel_source_dir} |
