aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/bcm5974.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2009-04-28 10:03:54 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-04-28 12:35:52 -0400
commit158e928741e58eb4aa379da422290c10fef23f00 (patch)
tree277a17d255f8773b483f6dc65b93d12a0f7b8756 /drivers/input/mouse/bcm5974.c
parent6916d97f6e25cc66a32d6e9a16419067d843b14f (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/bcm5974.c')
-rw-r--r--drivers/input/mouse/bcm5974.c45
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 */
100enum tp_type { 108enum 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 */
108struct tp_finger { 124struct tp_finger {
@@ -135,6 +151,7 @@ struct bcm5974_param {
135/* device-specific configuration */ 151/* device-specific configuration */
136struct bcm5974_config { 152struct 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);