diff options
author | Henrik Rydberg <rydberg@euromail.se> | 2009-04-28 10:03:54 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-04-28 12:35:52 -0400 |
commit | 158e928741e58eb4aa379da422290c10fef23f00 (patch) | |
tree | 277a17d255f8773b483f6dc65b93d12a0f7b8756 /drivers/input/mouse | |
parent | 6916d97f6e25cc66a32d6e9a16419067d843b14f (diff) |
Input: bcm5974 - Add support for the Macbook 5 (Unibody)
This patch adds support for the new unibody Macbook, with physically
integrated button and trackpad. Since the integrated button changes
the logic for touch-and-click, a device capability bit mask is now
reported in input_id.version, which can be picked up by user space
via a EVIOCGID call.
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Tested-by: David M. Lary <dmlary@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/mouse')
-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); |