diff options
| -rw-r--r-- | drivers/input/mouse/bcm5974.c | 74 | ||||
| -rw-r--r-- | drivers/input/serio/i8042-x86ia64io.h | 2 |
2 files changed, 58 insertions, 18 deletions
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 2ec921bf3c60..18f4d7f6ce6d 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
| @@ -63,7 +63,7 @@ | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | /* table of devices that work with this driver */ | 65 | /* table of devices that work with this driver */ |
| 66 | static const struct usb_device_id bcm5974_table [] = { | 66 | static const struct usb_device_id bcm5974_table[] = { |
| 67 | /* MacbookAir1.1 */ | 67 | /* MacbookAir1.1 */ |
| 68 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), | 68 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), |
| 69 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ISO), | 69 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ISO), |
| @@ -105,7 +105,7 @@ struct tp_header { | |||
| 105 | 105 | ||
| 106 | /* trackpad finger structure */ | 106 | /* trackpad finger structure */ |
| 107 | struct tp_finger { | 107 | struct tp_finger { |
| 108 | __le16 origin; /* left/right origin? */ | 108 | __le16 origin; /* zero when switching track finger */ |
| 109 | __le16 abs_x; /* absolute x coodinate */ | 109 | __le16 abs_x; /* absolute x coodinate */ |
| 110 | __le16 abs_y; /* absolute y coodinate */ | 110 | __le16 abs_y; /* absolute y coodinate */ |
| 111 | __le16 rel_x; /* relative x coodinate */ | 111 | __le16 rel_x; /* relative x coodinate */ |
| @@ -159,6 +159,7 @@ struct bcm5974 { | |||
| 159 | struct bt_data *bt_data; /* button transferred data */ | 159 | struct bt_data *bt_data; /* button transferred data */ |
| 160 | struct urb *tp_urb; /* trackpad usb request block */ | 160 | struct urb *tp_urb; /* trackpad usb request block */ |
| 161 | struct tp_data *tp_data; /* trackpad transferred data */ | 161 | struct tp_data *tp_data; /* trackpad transferred data */ |
| 162 | int fingers; /* number of fingers on trackpad */ | ||
| 162 | }; | 163 | }; |
| 163 | 164 | ||
| 164 | /* logical dimensions */ | 165 | /* logical dimensions */ |
| @@ -172,6 +173,10 @@ struct bcm5974 { | |||
| 172 | #define SN_WIDTH 100 /* width signal-to-noise ratio */ | 173 | #define SN_WIDTH 100 /* width signal-to-noise ratio */ |
| 173 | #define SN_COORD 250 /* coordinate signal-to-noise ratio */ | 174 | #define SN_COORD 250 /* coordinate signal-to-noise ratio */ |
| 174 | 175 | ||
| 176 | /* pressure thresholds */ | ||
| 177 | #define PRESSURE_LOW (2 * DIM_PRESSURE / SN_PRESSURE) | ||
| 178 | #define PRESSURE_HIGH (3 * PRESSURE_LOW) | ||
| 179 | |||
| 175 | /* device constants */ | 180 | /* device constants */ |
| 176 | static const struct bcm5974_config bcm5974_config_table[] = { | 181 | static const struct bcm5974_config bcm5974_config_table[] = { |
| 177 | { | 182 | { |
| @@ -248,6 +253,7 @@ static void setup_events_to_report(struct input_dev *input_dev, | |||
| 248 | 0, cfg->y.dim, cfg->y.fuzz, 0); | 253 | 0, cfg->y.dim, cfg->y.fuzz, 0); |
| 249 | 254 | ||
| 250 | __set_bit(EV_KEY, input_dev->evbit); | 255 | __set_bit(EV_KEY, input_dev->evbit); |
| 256 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
| 251 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | 257 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); |
| 252 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | 258 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); |
| 253 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | 259 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); |
| @@ -273,32 +279,66 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
| 273 | const struct tp_finger *f = dev->tp_data->finger; | 279 | const struct tp_finger *f = dev->tp_data->finger; |
| 274 | struct input_dev *input = dev->input; | 280 | struct input_dev *input = dev->input; |
| 275 | const int fingers = (size - 26) / 28; | 281 | const int fingers = (size - 26) / 28; |
| 276 | int p = 0, w, x, y, n = 0; | 282 | int raw_p, raw_w, raw_x, raw_y; |
| 283 | int ptest = 0, origin = 0, nmin = 0, nmax = 0; | ||
| 284 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; | ||
| 277 | 285 | ||
| 278 | if (size < 26 || (size - 26) % 28 != 0) | 286 | if (size < 26 || (size - 26) % 28 != 0) |
| 279 | return -EIO; | 287 | return -EIO; |
| 280 | 288 | ||
| 289 | /* always track the first finger; when detached, start over */ | ||
| 281 | if (fingers) { | 290 | if (fingers) { |
| 282 | p = raw2int(f->force_major); | 291 | raw_p = raw2int(f->force_major); |
| 283 | w = raw2int(f->size_major); | 292 | raw_w = raw2int(f->size_major); |
| 284 | x = raw2int(f->abs_x); | 293 | raw_x = raw2int(f->abs_x); |
| 285 | y = raw2int(f->abs_y); | 294 | raw_y = raw2int(f->abs_y); |
| 286 | n = p > 0 ? fingers : 0; | ||
| 287 | 295 | ||
| 288 | dprintk(9, | 296 | dprintk(9, |
| 289 | "bcm5974: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n", | 297 | "bcm5974: raw: p: %+05d w: %+05d x: %+05d y: %+05d\n", |
| 290 | p, w, x, y, n); | 298 | raw_p, raw_w, raw_x, raw_y); |
| 299 | |||
| 300 | ptest = int2bound(&c->p, raw_p); | ||
| 301 | origin = raw2int(f->origin); | ||
| 302 | } | ||
| 291 | 303 | ||
| 292 | input_report_abs(input, ABS_TOOL_WIDTH, int2bound(&c->w, w)); | 304 | /* while tracking finger still valid, count all fingers */ |
| 293 | input_report_abs(input, ABS_X, int2bound(&c->x, x - c->x.devmin)); | 305 | if (ptest > PRESSURE_LOW && origin) { |
| 294 | input_report_abs(input, ABS_Y, int2bound(&c->y, c->y.devmax - y)); | 306 | abs_p = ptest; |
| 307 | abs_w = int2bound(&c->w, raw_w); | ||
| 308 | abs_x = int2bound(&c->x, raw_x - c->x.devmin); | ||
| 309 | abs_y = int2bound(&c->y, c->y.devmax - raw_y); | ||
| 310 | for (; f != dev->tp_data->finger + fingers; f++) { | ||
| 311 | ptest = int2bound(&c->p, raw2int(f->force_major)); | ||
| 312 | if (ptest > PRESSURE_LOW) | ||
| 313 | nmax++; | ||
| 314 | if (ptest > PRESSURE_HIGH) | ||
| 315 | nmin++; | ||
| 316 | } | ||
| 295 | } | 317 | } |
| 296 | 318 | ||
| 297 | input_report_abs(input, ABS_PRESSURE, int2bound(&c->p, p)); | 319 | if (dev->fingers < nmin) |
| 320 | dev->fingers = nmin; | ||
| 321 | if (dev->fingers > nmax) | ||
| 322 | dev->fingers = nmax; | ||
| 323 | |||
| 324 | input_report_key(input, BTN_TOUCH, dev->fingers > 0); | ||
| 325 | input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1); | ||
| 326 | input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2); | ||
| 327 | input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers > 2); | ||
| 298 | 328 | ||
| 299 | input_report_key(input, BTN_TOOL_FINGER, n == 1); | 329 | input_report_abs(input, ABS_PRESSURE, abs_p); |
| 300 | input_report_key(input, BTN_TOOL_DOUBLETAP, n == 2); | 330 | input_report_abs(input, ABS_TOOL_WIDTH, abs_w); |
| 301 | input_report_key(input, BTN_TOOL_TRIPLETAP, n > 2); | 331 | |
| 332 | if (abs_p) { | ||
| 333 | input_report_abs(input, ABS_X, abs_x); | ||
| 334 | input_report_abs(input, ABS_Y, abs_y); | ||
| 335 | |||
| 336 | dprintk(8, | ||
| 337 | "bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d " | ||
| 338 | "nmin: %d nmax: %d n: %d\n", | ||
| 339 | abs_p, abs_w, abs_x, abs_y, nmin, nmax, dev->fingers); | ||
| 340 | |||
| 341 | } | ||
| 302 | 342 | ||
| 303 | input_sync(input); | 343 | input_sync(input); |
| 304 | 344 | ||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 3282b741e246..5aafe24984c5 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
| @@ -305,7 +305,7 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
| 305 | .ident = "Lenovo 3000 n100", | 305 | .ident = "Lenovo 3000 n100", |
| 306 | .matches = { | 306 | .matches = { |
| 307 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 307 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
| 308 | DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), | 308 | DMI_MATCH(DMI_PRODUCT_NAME, "076804U"), |
| 309 | }, | 309 | }, |
| 310 | }, | 310 | }, |
| 311 | { | 311 | { |
