diff options
| -rw-r--r-- | drivers/input/mouse/bcm5974.c | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 2ddf05e1d852..f2b38261eacb 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
| @@ -51,6 +51,10 @@ | |||
| 51 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 | 51 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 |
| 52 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 | 52 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 |
| 53 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 | 53 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 |
| 54 | /* Macbook5,1 (unibody), aka wellspring3 */ | ||
| 55 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 | ||
| 56 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 | ||
| 57 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 | ||
| 54 | 58 | ||
| 55 | #define BCM5974_DEVICE(prod) { \ | 59 | #define BCM5974_DEVICE(prod) { \ |
| 56 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ | 60 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ |
| @@ -72,6 +76,10 @@ static const struct usb_device_id bcm5974_table[] = { | |||
| 72 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI), | 76 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI), |
| 73 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ISO), | 77 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ISO), |
| 74 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), | 78 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), |
| 79 | /* Macbook5,1 */ | ||
| 80 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI), | ||
| 81 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO), | ||
| 82 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), | ||
| 75 | /* Terminating entry */ | 83 | /* Terminating entry */ |
| 76 | {} | 84 | {} |
| 77 | }; | 85 | }; |
| @@ -98,11 +106,19 @@ struct bt_data { | |||
| 98 | 106 | ||
| 99 | /* trackpad header types */ | 107 | /* trackpad header types */ |
| 100 | enum tp_type { | 108 | enum tp_type { |
| 101 | TYPE1 /* plain trackpad */ | 109 | TYPE1, /* plain trackpad */ |
| 110 | TYPE2 /* button integrated in trackpad */ | ||
| 102 | }; | 111 | }; |
| 103 | 112 | ||
| 104 | /* trackpad finger data offsets, le16-aligned */ | 113 | /* trackpad finger data offsets, le16-aligned */ |
| 105 | #define FINGER_TYPE1 (13 * sizeof(__le16)) | 114 | #define FINGER_TYPE1 (13 * sizeof(__le16)) |
| 115 | #define FINGER_TYPE2 (15 * sizeof(__le16)) | ||
| 116 | |||
| 117 | /* trackpad button data offsets */ | ||
| 118 | #define BUTTON_TYPE2 15 | ||
| 119 | |||
| 120 | /* list of device capability bits */ | ||
| 121 | #define HAS_INTEGRATED_BUTTON 1 | ||
| 106 | 122 | ||
| 107 | /* trackpad finger structure, le16-aligned */ | 123 | /* trackpad finger structure, le16-aligned */ |
| 108 | struct tp_finger { | 124 | struct tp_finger { |
| @@ -135,6 +151,7 @@ struct bcm5974_param { | |||
| 135 | /* device-specific configuration */ | 151 | /* device-specific configuration */ |
| 136 | struct bcm5974_config { | 152 | struct bcm5974_config { |
| 137 | int ansi, iso, jis; /* the product id of this device */ | 153 | int ansi, iso, jis; /* the product id of this device */ |
| 154 | int caps; /* device capability bitmask */ | ||
| 138 | int bt_ep; /* the endpoint of the button interface */ | 155 | int bt_ep; /* the endpoint of the button interface */ |
| 139 | int bt_datalen; /* data length of the button interface */ | 156 | int bt_datalen; /* data length of the button interface */ |
| 140 | int tp_ep; /* the endpoint of the trackpad interface */ | 157 | int tp_ep; /* the endpoint of the trackpad interface */ |
| @@ -184,6 +201,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
| 184 | USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, | 201 | USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, |
| 185 | USB_DEVICE_ID_APPLE_WELLSPRING_ISO, | 202 | USB_DEVICE_ID_APPLE_WELLSPRING_ISO, |
| 186 | USB_DEVICE_ID_APPLE_WELLSPRING_JIS, | 203 | USB_DEVICE_ID_APPLE_WELLSPRING_JIS, |
| 204 | 0, | ||
| 187 | 0x84, sizeof(struct bt_data), | 205 | 0x84, sizeof(struct bt_data), |
| 188 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, | 206 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, |
| 189 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, | 207 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, |
| @@ -195,6 +213,7 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
| 195 | USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, | 213 | USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, |
| 196 | USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, | 214 | USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, |
| 197 | USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, | 215 | USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, |
| 216 | 0, | ||
| 198 | 0x84, sizeof(struct bt_data), | 217 | 0x84, sizeof(struct bt_data), |
| 199 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, | 218 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, |
| 200 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, | 219 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, |
| @@ -202,6 +221,18 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
| 202 | { DIM_X, DIM_X / SN_COORD, -4824, 4824 }, | 221 | { DIM_X, DIM_X / SN_COORD, -4824, 4824 }, |
| 203 | { DIM_Y, DIM_Y / SN_COORD, -172, 4290 } | 222 | { DIM_Y, DIM_Y / SN_COORD, -172, 4290 } |
| 204 | }, | 223 | }, |
| 224 | { | ||
| 225 | USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI, | ||
| 226 | USB_DEVICE_ID_APPLE_WELLSPRING3_ISO, | ||
| 227 | USB_DEVICE_ID_APPLE_WELLSPRING3_JIS, | ||
| 228 | HAS_INTEGRATED_BUTTON, | ||
| 229 | 0x84, sizeof(struct bt_data), | ||
| 230 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | ||
| 231 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | ||
| 232 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | ||
| 233 | { DIM_X, DIM_X / SN_COORD, -4460, 5166 }, | ||
| 234 | { DIM_Y, DIM_Y / SN_COORD, -75, 6700 } | ||
| 235 | }, | ||
| 205 | {} | 236 | {} |
| 206 | }; | 237 | }; |
| 207 | 238 | ||
| @@ -281,7 +312,7 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
| 281 | const struct tp_finger *f; | 312 | const struct tp_finger *f; |
| 282 | struct input_dev *input = dev->input; | 313 | struct input_dev *input = dev->input; |
| 283 | int raw_p, raw_w, raw_x, raw_y, raw_n; | 314 | int raw_p, raw_w, raw_x, raw_y, raw_n; |
| 284 | int ptest = 0, origin = 0, nmin = 0, nmax = 0; | 315 | int ptest = 0, origin = 0, ibt = 0, nmin = 0, nmax = 0; |
| 285 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; | 316 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; |
| 286 | 317 | ||
| 287 | if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) | 318 | if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) |
| @@ -304,6 +335,10 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
| 304 | 335 | ||
| 305 | ptest = int2bound(&c->p, raw_p); | 336 | ptest = int2bound(&c->p, raw_p); |
| 306 | origin = raw2int(f->origin); | 337 | origin = raw2int(f->origin); |
| 338 | |||
| 339 | /* set the integrated button if applicable */ | ||
| 340 | if (c->tp_type == TYPE2) | ||
| 341 | ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); | ||
| 307 | } | 342 | } |
| 308 | 343 | ||
| 309 | /* while tracking finger still valid, count all fingers */ | 344 | /* while tracking finger still valid, count all fingers */ |
| @@ -347,6 +382,10 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
| 347 | 382 | ||
| 348 | } | 383 | } |
| 349 | 384 | ||
| 385 | /* type 2 reports button events via ibt only */ | ||
| 386 | if (c->tp_type == TYPE2) | ||
| 387 | input_report_key(input, BTN_LEFT, ibt); | ||
| 388 | |||
| 350 | input_sync(input); | 389 | input_sync(input); |
| 351 | 390 | ||
| 352 | return 0; | 391 | return 0; |
| @@ -656,6 +695,8 @@ static int bcm5974_probe(struct usb_interface *iface, | |||
| 656 | input_dev->name = "bcm5974"; | 695 | input_dev->name = "bcm5974"; |
| 657 | input_dev->phys = dev->phys; | 696 | input_dev->phys = dev->phys; |
| 658 | usb_to_input_id(dev->udev, &input_dev->id); | 697 | usb_to_input_id(dev->udev, &input_dev->id); |
| 698 | /* report driver capabilities via the version field */ | ||
| 699 | input_dev->id.version = cfg->caps; | ||
| 659 | input_dev->dev.parent = &iface->dev; | 700 | input_dev->dev.parent = &iface->dev; |
| 660 | 701 | ||
| 661 | input_set_drvdata(input_dev, dev); | 702 | input_set_drvdata(input_dev, dev); |
