1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Apple USB BCM5974 (Macbook Air and Penryn Macbook Pro) multitouch driver 4 * 5 * Copyright (C) 2008 Henrik Rydberg (rydberg@euromail.se) 6 * Copyright (C) 2015 John Horan (knasher@gmail.com) 7 * 8 * The USB initialization and package decoding was made by 9 * Scott Shawcroft as part of the touchd user-space driver project: 10 * Copyright (C) 2008 Scott Shawcroft (scott.shawcroft@gmail.com) 11 * 12 * The BCM5974 driver is based on the appletouch driver: 13 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) 14 * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net) 15 * Copyright (C) 2005 Stelian Pop (stelian@popies.net) 16 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) 17 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) 18 * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch) 19 * Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch) 20 */ 21 22 #include "linux/usb.h" 23 #include <linux/kernel.h> 24 #include <linux/errno.h> 25 #include <linux/slab.h> 26 #include <linux/module.h> 27 #include <linux/usb/input.h> 28 #include <linux/hid.h> 29 #include <linux/mutex.h> 30 #include <linux/input/mt.h> 31 32 #define USB_VENDOR_ID_APPLE 0x05ac 33 34 /* MacbookAir, aka wellspring */ 35 #define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223 36 #define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224 37 #define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225 38 /* MacbookProPenryn, aka wellspring2 */ 39 #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 40 #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 41 #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 42 /* Macbook5,1 (unibody), aka wellspring3 */ 43 #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 44 #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 45 #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 46 /* MacbookAir3,2 (unibody), aka wellspring5 */ 47 #define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f 48 #define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240 49 #define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241 50 /* MacbookAir3,1 (unibody), aka wellspring4 */ 51 #define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242 52 #define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243 53 #define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244 54 /* Macbook8 (unibody, March 2011) */ 55 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245 56 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246 57 #define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247 58 /* MacbookAir4,1 (unibody, July 2011) */ 59 #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249 60 #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a 61 #define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b 62 /* MacbookAir4,2 (unibody, July 2011) */ 63 #define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI 0x024c 64 #define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO 0x024d 65 #define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS 0x024e 66 /* Macbook8,2 (unibody) */ 67 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252 68 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253 69 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254 70 /* MacbookPro10,1 (unibody, June 2012) */ 71 #define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262 72 #define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263 73 #define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264 74 /* MacbookPro10,2 (unibody, October 2012) */ 75 #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259 76 #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a 77 #define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b 78 /* MacbookAir6,2 (unibody, June 2013) */ 79 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 80 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 81 #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 82 /* MacbookPro12,1 (2015) */ 83 #define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272 84 #define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273 85 #define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274 86 87 #define BCM5974_DEVICE(prod) { \ 88 .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ 89 USB_DEVICE_ID_MATCH_INT_CLASS | \ 90 USB_DEVICE_ID_MATCH_INT_PROTOCOL), \ 91 .idVendor = USB_VENDOR_ID_APPLE, \ 92 .idProduct = (prod), \ 93 .bInterfaceClass = USB_INTERFACE_CLASS_HID, \ 94 .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE \ 95 } 96 97 /* table of devices that work with this driver */ 98 static const struct usb_device_id bcm5974_table[] = { 99 /* MacbookAir1.1 */ 100 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), 101 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ISO), 102 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_JIS), 103 /* MacbookProPenryn */ 104 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI), 105 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ISO), 106 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), 107 /* Macbook5,1 */ 108 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI), 109 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO), 110 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), 111 /* MacbookAir3,2 */ 112 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI), 113 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ISO), 114 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_JIS), 115 /* MacbookAir3,1 */ 116 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI), 117 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO), 118 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS), 119 /* MacbookPro8 */ 120 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI), 121 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_ISO), 122 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_JIS), 123 /* MacbookAir4,1 */ 124 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI), 125 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO), 126 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS), 127 /* MacbookAir4,2 */ 128 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI), 129 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6_ISO), 130 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6_JIS), 131 /* MacbookPro8,2 */ 132 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI), 133 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO), 134 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS), 135 /* MacbookPro10,1 */ 136 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI), 137 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ISO), 138 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), 139 /* MacbookPro10,2 */ 140 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI), 141 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO), 142 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS), 143 /* MacbookAir6,2 */ 144 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI), 145 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ISO), 146 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_JIS), 147 /* MacbookPro12,1 */ 148 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI), 149 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_ISO), 150 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_JIS), 151 /* Terminating entry */ 152 {} 153 }; 154 MODULE_DEVICE_TABLE(usb, bcm5974_table); 155 156 MODULE_AUTHOR("Henrik Rydberg"); 157 MODULE_DESCRIPTION("Apple USB BCM5974 multitouch driver"); 158 MODULE_LICENSE("GPL"); 159 160 #define dprintk(level, format, a...)\ 161 { if (debug >= level) printk(KERN_DEBUG format, ##a); } 162 163 static int debug = 1; 164 module_param(debug, int, 0644); 165 MODULE_PARM_DESC(debug, "Activate debugging output"); 166 167 /* button data structure */ 168 struct bt_data { 169 u8 unknown1; /* constant */ 170 u8 button; /* left button */ 171 u8 rel_x; /* relative x coordinate */ 172 u8 rel_y; /* relative y coordinate */ 173 }; 174 175 /* trackpad header types */ 176 enum tp_type { 177 TYPE1, /* plain trackpad */ 178 TYPE2, /* button integrated in trackpad */ 179 TYPE3, /* additional header fields since June 2013 */ 180 TYPE4 /* additional header field for pressure data */ 181 }; 182 183 /* trackpad finger data offsets, le16-aligned */ 184 #define HEADER_TYPE1 (13 * sizeof(__le16)) 185 #define HEADER_TYPE2 (15 * sizeof(__le16)) 186 #define HEADER_TYPE3 (19 * sizeof(__le16)) 187 #define HEADER_TYPE4 (23 * sizeof(__le16)) 188 189 /* trackpad button data offsets */ 190 #define BUTTON_TYPE1 0 191 #define BUTTON_TYPE2 15 192 #define BUTTON_TYPE3 23 193 #define BUTTON_TYPE4 31 194 195 /* list of device capability bits */ 196 #define HAS_INTEGRATED_BUTTON 1 197 /* maximum number of supported endpoints (currently trackpad and button) */ 198 #define MAX_ENDPOINTS 2 199 200 /* trackpad finger data block size */ 201 #define FSIZE_TYPE1 (14 * sizeof(__le16)) 202 #define FSIZE_TYPE2 (14 * sizeof(__le16)) 203 #define FSIZE_TYPE3 (14 * sizeof(__le16)) 204 #define FSIZE_TYPE4 (15 * sizeof(__le16)) 205 206 /* offset from header to finger struct */ 207 #define DELTA_TYPE1 (0 * sizeof(__le16)) 208 #define DELTA_TYPE2 (0 * sizeof(__le16)) 209 #define DELTA_TYPE3 (0 * sizeof(__le16)) 210 #define DELTA_TYPE4 (1 * sizeof(__le16)) 211 212 /* usb control message mode switch data */ 213 #define USBMSG_TYPE1 8, 0x300, 0, 0, 0x1, 0x8 214 #define USBMSG_TYPE2 8, 0x300, 0, 0, 0x1, 0x8 215 #define USBMSG_TYPE3 8, 0x300, 0, 0, 0x1, 0x8 216 #define USBMSG_TYPE4 2, 0x302, 2, 1, 0x1, 0x0 217 218 /* Wellspring initialization constants */ 219 #define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID 1 220 #define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID 9 221 222 /* trackpad finger structure, le16-aligned */ 223 struct tp_finger { 224 __le16 origin; /* zero when switching track finger */ 225 __le16 abs_x; /* absolute x coodinate */ 226 __le16 abs_y; /* absolute y coodinate */ 227 __le16 rel_x; /* relative x coodinate */ 228 __le16 rel_y; /* relative y coodinate */ 229 __le16 tool_major; /* tool area, major axis */ 230 __le16 tool_minor; /* tool area, minor axis */ 231 __le16 orientation; /* 16384 when point, else 15 bit angle */ 232 __le16 touch_major; /* touch area, major axis */ 233 __le16 touch_minor; /* touch area, minor axis */ 234 __le16 unused[2]; /* zeros */ 235 __le16 pressure; /* pressure on forcetouch touchpad */ 236 __le16 multi; /* one finger: varies, more fingers: constant */ 237 } __attribute__((packed,aligned(2))); 238 239 /* trackpad finger data size, empirically at least ten fingers */ 240 #define MAX_FINGERS 16 241 #define MAX_FINGER_ORIENTATION 16384 242 243 /* device-specific parameters */ 244 struct bcm5974_param { 245 int snratio; /* signal-to-noise ratio */ 246 int min; /* device minimum reading */ 247 int max; /* device maximum reading */ 248 }; 249 250 /* device-specific configuration */ 251 struct bcm5974_config { 252 int ansi, iso, jis; /* the product id of this device */ 253 int caps; /* device capability bitmask */ 254 int bt_ep; /* the endpoint of the button interface */ 255 int bt_datalen; /* data length of the button interface */ 256 int tp_ep; /* the endpoint of the trackpad interface */ 257 enum tp_type tp_type; /* type of trackpad interface */ 258 int tp_header; /* bytes in header block */ 259 int tp_datalen; /* data length of the trackpad interface */ 260 int tp_button; /* offset to button data */ 261 int tp_fsize; /* bytes in single finger block */ 262 int tp_delta; /* offset from header to finger struct */ 263 int um_size; /* usb control message length */ 264 int um_req_val; /* usb control message value */ 265 int um_req_idx; /* usb control message index */ 266 int um_switch_idx; /* usb control message mode switch index */ 267 int um_switch_on; /* usb control message mode switch on */ 268 int um_switch_off; /* usb control message mode switch off */ 269 struct bcm5974_param p; /* finger pressure limits */ 270 struct bcm5974_param w; /* finger width limits */ 271 struct bcm5974_param x; /* horizontal limits */ 272 struct bcm5974_param y; /* vertical limits */ 273 struct bcm5974_param o; /* orientation limits */ 274 }; 275 276 /* logical device structure */ 277 struct bcm5974 { 278 char phys[64]; 279 struct usb_device *udev; /* usb device */ 280 struct usb_interface *intf; /* our interface */ 281 struct input_dev *input; /* input dev */ 282 struct bcm5974_config cfg; /* device configuration */ 283 struct mutex pm_mutex; /* serialize access to open/suspend */ 284 int opened; /* 1: opened, 0: closed */ 285 struct urb *bt_urb; /* button usb request block */ 286 struct bt_data *bt_data; /* button transferred data */ 287 struct urb *tp_urb; /* trackpad usb request block */ 288 u8 *tp_data; /* trackpad transferred data */ 289 const struct tp_finger *index[MAX_FINGERS]; /* finger index data */ 290 struct input_mt_pos pos[MAX_FINGERS]; /* position array */ 291 int slots[MAX_FINGERS]; /* slot assignments */ 292 }; 293 294 /* trackpad finger block data, le16-aligned */ 295 static const struct tp_finger *get_tp_finger(const struct bcm5974 *dev, int i) 296 { 297 const struct bcm5974_config *c = &dev->cfg; 298 u8 *f_base = dev->tp_data + c->tp_header + c->tp_delta; 299 300 return (const struct tp_finger *)(f_base + i * c->tp_fsize); 301 } 302 303 #define DATAFORMAT(type) \ 304 type, \ 305 HEADER_##type, \ 306 HEADER_##type + (MAX_FINGERS) * (FSIZE_##type), \ 307 BUTTON_##type, \ 308 FSIZE_##type, \ 309 DELTA_##type, \ 310 USBMSG_##type 311 312 /* logical signal quality */ 313 #define SN_PRESSURE 45 /* pressure signal-to-noise ratio */ 314 #define SN_WIDTH 25 /* width signal-to-noise ratio */ 315 #define SN_COORD 250 /* coordinate signal-to-noise ratio */ 316 #define SN_ORIENT 10 /* orientation signal-to-noise ratio */ 317 318 /* device constants */ 319 static const struct bcm5974_config bcm5974_config_table[] = { 320 { 321 USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, 322 USB_DEVICE_ID_APPLE_WELLSPRING_ISO, 323 USB_DEVICE_ID_APPLE_WELLSPRING_JIS, 324 0, 325 0x84, sizeof(struct bt_data), 326 0x81, DATAFORMAT(TYPE1), 327 { SN_PRESSURE, 0, 256 }, 328 { SN_WIDTH, 0, 2048 }, 329 { SN_COORD, -4824, 5342 }, 330 { SN_COORD, -172, 5820 }, 331 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } 332 }, 333 { 334 USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, 335 USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, 336 USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, 337 0, 338 0x84, sizeof(struct bt_data), 339 0x81, DATAFORMAT(TYPE1), 340 { SN_PRESSURE, 0, 256 }, 341 { SN_WIDTH, 0, 2048 }, 342 { SN_COORD, -4824, 4824 }, 343 { SN_COORD, -172, 4290 }, 344 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } 345 }, 346 { 347 USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI, 348 USB_DEVICE_ID_APPLE_WELLSPRING3_ISO, 349 USB_DEVICE_ID_APPLE_WELLSPRING3_JIS, 350 HAS_INTEGRATED_BUTTON, 351 0x84, sizeof(struct bt_data), 352 0x81, DATAFORMAT(TYPE2), 353 { SN_PRESSURE, 0, 300 }, 354 { SN_WIDTH, 0, 2048 }, 355 { SN_COORD, -4460, 5166 }, 356 { SN_COORD, -75, 6700 }, 357 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } 358 }, 359 { 360 USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI, 361 USB_DEVICE_ID_APPLE_WELLSPRING4_ISO, 362 USB_DEVICE_ID_APPLE_WELLSPRING4_JIS, 363 HAS_INTEGRATED_BUTTON, 364 0x84, sizeof(struct bt_data), 365 0x81, DATAFORMAT(TYPE2), 366 { SN_PRESSURE, 0, 300 }, 367 { SN_WIDTH, 0, 2048 }, 368 { SN_COORD, -4620, 5140 }, 369 { SN_COORD, -150, 6600 }, 370 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } 371 }, 372 { 373 USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI, 374 USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO, 375 USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS, 376 HAS_INTEGRATED_BUTTON, 377 0x84, sizeof(struct bt_data), 378 0x81, DATAFORMAT(TYPE2), 379 { SN_PRESSURE, 0, 300 }, 380 { SN_WIDTH, 0, 2048 }, 381 { SN_COORD, -4616, 5112 }, 382 { SN_COORD, -142, 5234 }, 383 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } 384 }, 385 { 386 USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI, 387 USB_DEVICE_ID_APPLE_WELLSPRING5_ISO, 388 USB_DEVICE_ID_APPLE_WELLSPRING5_JIS, 389 HAS_INTEGRATED_BUTTON, 390 0x84, sizeof(struct bt_data), 391 0x81, DATAFORMAT(TYPE2), 392 { SN_PRESSURE, 0, 300 }, 393 { SN_WIDTH, 0, 2048 }, 394 { SN_COORD, -4415, 5050 }, 395 { SN_COORD, -55, 6680 }, 396 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } 397 }, 398 { 399 USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI, 400 USB_DEVICE_ID_APPLE_WELLSPRING6_ISO, 401 USB_DEVICE_ID_APPLE_WELLSPRING6_JIS, 402 HAS_INTEGRATED_BUTTON, 403 0x84, sizeof(struct bt_data), 404 0x81, DATAFORMAT(TYPE2), 405 { SN_PRESSURE, 0, 300 }, 406 { SN_WIDTH, 0, 2048 }, 407 { SN_COORD, -4620, 5140 }, 408 { SN_COORD, -150, 6600 }, 409 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } 410 }, 411 { 412 USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI, 413 USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO, 414 USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS, 415 HAS_INTEGRATED_BUTTON, 416 0x84, sizeof(struct bt_data), 417 0x81, DATAFORMAT(TYPE2), 418 { SN_PRESSURE, 0, 300 }, 419 { SN_WIDTH, 0, 2048 }, 420 { SN_COORD, -4750, 5280 }, 421 { SN_COORD, -150, 6730 }, 422 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } 423 }, 424 { 425 USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI, 426 USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO, 427 USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS, 428 HAS_INTEGRATED_BUTTON, 429 0x84, sizeof(struct bt_data), 430 0x81, DATAFORMAT(TYPE2), 431 { SN_PRESSURE, 0, 300 }, 432 { SN_WIDTH, 0, 2048 }, 433 { SN_COORD, -4620, 5140 }, 434 { SN_COORD, -150, 6600 }, 435 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } 436 }, 437 { 438 USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI, 439 USB_DEVICE_ID_APPLE_WELLSPRING7_ISO, 440 USB_DEVICE_ID_APPLE_WELLSPRING7_JIS, 441 HAS_INTEGRATED_BUTTON, 442 0x84, sizeof(struct bt_data), 443 0x81, DATAFORMAT(TYPE2), 444 { SN_PRESSURE, 0, 300 }, 445 { SN_WIDTH, 0, 2048 }, 446 { SN_COORD, -4750, 5280 }, 447 { SN_COORD, -150, 6730 }, 448 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } 449 }, 450 { 451 USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI, 452 USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO, 453 USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS, 454 HAS_INTEGRATED_BUTTON, 455 0x84, sizeof(struct bt_data), 456 0x81, DATAFORMAT(TYPE2), 457 { SN_PRESSURE, 0, 300 }, 458 { SN_WIDTH, 0, 2048 }, 459 { SN_COORD, -4750, 5280 }, 460 { SN_COORD, -150, 6730 }, 461 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } 462 }, 463 { 464 USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI, 465 USB_DEVICE_ID_APPLE_WELLSPRING8_ISO, 466 USB_DEVICE_ID_APPLE_WELLSPRING8_JIS, 467 HAS_INTEGRATED_BUTTON, 468 0, sizeof(struct bt_data), 469 0x83, DATAFORMAT(TYPE3), 470 { SN_PRESSURE, 0, 300 }, 471 { SN_WIDTH, 0, 2048 }, 472 { SN_COORD, -4620, 5140 }, 473 { SN_COORD, -150, 6600 }, 474 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } 475 }, 476 { 477 USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI, 478 USB_DEVICE_ID_APPLE_WELLSPRING9_ISO, 479 USB_DEVICE_ID_APPLE_WELLSPRING9_JIS, 480 HAS_INTEGRATED_BUTTON, 481 0, sizeof(struct bt_data), 482 0x83, DATAFORMAT(TYPE4), 483 { SN_PRESSURE, 0, 300 }, 484 { SN_WIDTH, 0, 2048 }, 485 { SN_COORD, -4828, 5345 }, 486 { SN_COORD, -203, 6803 }, 487 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } 488 }, 489 {} 490 }; 491 492 /* return the device-specific configuration by device */ 493 static const struct bcm5974_config *bcm5974_get_config(struct usb_device *udev) 494 { 495 u16 id = le16_to_cpu(udev->descriptor.idProduct); 496 const struct bcm5974_config *cfg; 497 498 for (cfg = bcm5974_config_table; cfg->ansi; ++cfg) 499 if (cfg->ansi == id || cfg->iso == id || cfg->jis == id) 500 return cfg; 501 502 return bcm5974_config_table; 503 } 504 505 /* convert 16-bit little endian to signed integer */ 506 static inline int raw2int(__le16 x) 507 { 508 return (signed short)le16_to_cpu(x); 509 } 510 511 static void set_abs(struct input_dev *input, unsigned int code, 512 const struct bcm5974_param *p) 513 { 514 int fuzz = p->snratio ? (p->max - p->min) / p->snratio : 0; 515 input_set_abs_params(input, code, p->min, p->max, fuzz, 0); 516 } 517 518 /* setup which logical events to report */ 519 static void setup_events_to_report(struct input_dev *input_dev, 520 const struct bcm5974_config *cfg) 521 { 522 __set_bit(EV_ABS, input_dev->evbit); 523 524 /* for synaptics only */ 525 input_set_abs_params(input_dev, ABS_PRESSURE, 0, 256, 5, 0); 526 input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 16, 0, 0); 527 528 /* finger touch area */ 529 set_abs(input_dev, ABS_MT_TOUCH_MAJOR, &cfg->w); 530 set_abs(input_dev, ABS_MT_TOUCH_MINOR, &cfg->w); 531 /* finger approach area */ 532 set_abs(input_dev, ABS_MT_WIDTH_MAJOR, &cfg->w); 533 set_abs(input_dev, ABS_MT_WIDTH_MINOR, &cfg->w); 534 /* finger orientation */ 535 set_abs(input_dev, ABS_MT_ORIENTATION, &cfg->o); 536 /* finger position */ 537 set_abs(input_dev, ABS_MT_POSITION_X, &cfg->x); 538 set_abs(input_dev, ABS_MT_POSITION_Y, &cfg->y); 539 540 __set_bit(EV_KEY, input_dev->evbit); 541 __set_bit(BTN_LEFT, input_dev->keybit); 542 543 if (cfg->caps & HAS_INTEGRATED_BUTTON) 544 __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); 545 546 input_mt_init_slots(input_dev, MAX_FINGERS, 547 INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); 548 } 549 550 /* report button data as logical button state */ 551 static int report_bt_state(struct bcm5974 *dev, int size) 552 { 553 if (size != sizeof(struct bt_data)) 554 return -EIO; 555 556 dprintk(7, 557 "bcm5974: button data: %x %x %x %x\n", 558 dev->bt_data->unknown1, dev->bt_data->button, 559 dev->bt_data->rel_x, dev->bt_data->rel_y); 560 561 input_report_key(dev->input, BTN_LEFT, dev->bt_data->button); 562 input_sync(dev->input); 563 564 return 0; 565 } 566 567 static void report_finger_data(struct input_dev *input, int slot, 568 const struct input_mt_pos *pos, 569 const struct tp_finger *f) 570 { 571 input_mt_slot(input, slot); 572 input_mt_report_slot_state(input, MT_TOOL_FINGER, true); 573 574 input_report_abs(input, ABS_MT_TOUCH_MAJOR, 575 raw2int(f->touch_major) << 1); 576 input_report_abs(input, ABS_MT_TOUCH_MINOR, 577 raw2int(f->touch_minor) << 1); 578 input_report_abs(input, ABS_MT_WIDTH_MAJOR, 579 raw2int(f->tool_major) << 1); 580 input_report_abs(input, ABS_MT_WIDTH_MINOR, 581 raw2int(f->tool_minor) << 1); 582 input_report_abs(input, ABS_MT_ORIENTATION, 583 MAX_FINGER_ORIENTATION - raw2int(f->orientation)); 584 input_report_abs(input, ABS_MT_POSITION_X, pos->x); 585 input_report_abs(input, ABS_MT_POSITION_Y, pos->y); 586 } 587 588 static void report_synaptics_data(struct input_dev *input, 589 const struct bcm5974_config *cfg, 590 const struct tp_finger *f, int raw_n) 591 { 592 int abs_p = 0, abs_w = 0; 593 594 if (raw_n) { 595 int p = raw2int(f->touch_major); 596 int w = raw2int(f->tool_major); 597 if (p > 0 && raw2int(f->origin)) { 598 abs_p = clamp_val(256 * p / cfg->p.max, 0, 255); 599 abs_w = clamp_val(16 * w / cfg->w.max, 0, 15); 600 } 601 } 602 603 input_report_abs(input, ABS_PRESSURE, abs_p); 604 input_report_abs(input, ABS_TOOL_WIDTH, abs_w); 605 } 606 607 /* report trackpad data as logical trackpad state */ 608 static int report_tp_state(struct bcm5974 *dev, int size) 609 { 610 const struct bcm5974_config *c = &dev->cfg; 611 const struct tp_finger *f; 612 struct input_dev *input = dev->input; 613 int raw_n, i, n = 0; 614 615 if (size < c->tp_header || (size - c->tp_header) % c->tp_fsize != 0) 616 return -EIO; 617 618 raw_n = (size - c->tp_header) / c->tp_fsize; 619 620 for (i = 0; i < raw_n; i++) { 621 f = get_tp_finger(dev, i); 622 if (raw2int(f->touch_major) == 0) 623 continue; 624 dev->pos[n].x = raw2int(f->abs_x); 625 dev->pos[n].y = c->y.min + c->y.max - raw2int(f->abs_y); 626 dev->index[n++] = f; 627 } 628 629 input_mt_assign_slots(input, dev->slots, dev->pos, n, 0); 630 631 for (i = 0; i < n; i++) 632 report_finger_data(input, dev->slots[i], 633 &dev->pos[i], dev->index[i]); 634 635 input_mt_sync_frame(input); 636 637 report_synaptics_data(input, c, get_tp_finger(dev, 0), raw_n); 638 639 /* later types report button events via integrated button only */ 640 if (c->caps & HAS_INTEGRATED_BUTTON) { 641 int ibt = raw2int(dev->tp_data[c->tp_button]); 642 input_report_key(input, BTN_LEFT, ibt); 643 } 644 645 input_sync(input); 646 647 return 0; 648 } 649 650 static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on) 651 { 652 const struct bcm5974_config *c = &dev->cfg; 653 int retval = 0, size; 654 char *data; 655 656 /* Type 3 does not require a mode switch */ 657 if (c->tp_type == TYPE3) 658 return 0; 659 660 data = kmalloc(c->um_size, GFP_KERNEL); 661 if (!data) { 662 dev_err(&dev->intf->dev, "out of memory\n"); 663 retval = -ENOMEM; 664 goto out; 665 } 666 667 /* read configuration */ 668 size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), 669 BCM5974_WELLSPRING_MODE_READ_REQUEST_ID, 670 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 671 c->um_req_val, c->um_req_idx, data, c->um_size, 5000); 672 673 if (size != c->um_size) { 674 dev_err(&dev->intf->dev, "could not read from device\n"); 675 retval = -EIO; 676 goto out; 677 } 678 679 /* apply the mode switch */ 680 data[c->um_switch_idx] = on ? c->um_switch_on : c->um_switch_off; 681 682 /* write configuration */ 683 size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), 684 BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID, 685 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 686 c->um_req_val, c->um_req_idx, data, c->um_size, 5000); 687 688 if (size != c->um_size) { 689 dev_err(&dev->intf->dev, "could not write to device\n"); 690 retval = -EIO; 691 goto out; 692 } 693 694 dprintk(2, "bcm5974: switched to %s mode.\n", 695 on ? "wellspring" : "normal"); 696 697 out: 698 kfree(data); 699 return retval; 700 } 701 702 static void bcm5974_irq_button(struct urb *urb) 703 { 704 struct bcm5974 *dev = urb->context; 705 struct usb_interface *intf = dev->intf; 706 int error; 707 708 switch (urb->status) { 709 case 0: 710 break; 711 case -EOVERFLOW: 712 case -ECONNRESET: 713 case -ENOENT: 714 case -ESHUTDOWN: 715 dev_dbg(&intf->dev, "button urb shutting down: %d\n", 716 urb->status); 717 return; 718 default: 719 dev_dbg(&intf->dev, "button urb status: %d\n", urb->status); 720 goto exit; 721 } 722 723 if (report_bt_state(dev, dev->bt_urb->actual_length)) 724 dprintk(1, "bcm5974: bad button package, length: %d\n", 725 dev->bt_urb->actual_length); 726 727 exit: 728 error = usb_submit_urb(dev->bt_urb, GFP_ATOMIC); 729 if (error) 730 dev_err(&intf->dev, "button urb failed: %d\n", error); 731 } 732 733 static void bcm5974_irq_trackpad(struct urb *urb) 734 { 735 struct bcm5974 *dev = urb->context; 736 struct usb_interface *intf = dev->intf; 737 int error; 738 739 switch (urb->status) { 740 case 0: 741 break; 742 case -EOVERFLOW: 743 case -ECONNRESET: 744 case -ENOENT: 745 case -ESHUTDOWN: 746 dev_dbg(&intf->dev, "trackpad urb shutting down: %d\n", 747 urb->status); 748 return; 749 default: 750 dev_dbg(&intf->dev, "trackpad urb status: %d\n", urb->status); 751 goto exit; 752 } 753 754 /* control response ignored */ 755 if (dev->tp_urb->actual_length == 2) 756 goto exit; 757 758 if (report_tp_state(dev, dev->tp_urb->actual_length)) 759 dprintk(1, "bcm5974: bad trackpad package, length: %d\n", 760 dev->tp_urb->actual_length); 761 762 exit: 763 error = usb_submit_urb(dev->tp_urb, GFP_ATOMIC); 764 if (error) 765 dev_err(&intf->dev, "trackpad urb failed: %d\n", error); 766 } 767 768 /* 769 * The Wellspring trackpad, like many recent Apple trackpads, share 770 * the usb device with the keyboard. Since keyboards are usually 771 * handled by the HID system, the device ends up being handled by two 772 * modules. Setting up the device therefore becomes slightly 773 * complicated. To enable multitouch features, a mode switch is 774 * required, which is usually applied via the control interface of the 775 * device. It can be argued where this switch should take place. In 776 * some drivers, like appletouch, the switch is made during 777 * probe. However, the hid module may also alter the state of the 778 * device, resulting in trackpad malfunction under certain 779 * circumstances. To get around this problem, there is at least one 780 * example that utilizes the USB_QUIRK_RESET_RESUME quirk in order to 781 * receive a reset_resume request rather than the normal resume. 782 * Since the implementation of reset_resume is equal to mode switch 783 * plus start_traffic, it seems easier to always do the switch when 784 * starting traffic on the device. 785 */ 786 static int bcm5974_start_traffic(struct bcm5974 *dev) 787 { 788 int error; 789 790 error = bcm5974_wellspring_mode(dev, true); 791 if (error) { 792 dprintk(1, "bcm5974: mode switch failed\n"); 793 goto err_out; 794 } 795 796 if (dev->bt_urb) { 797 error = usb_submit_urb(dev->bt_urb, GFP_KERNEL); 798 if (error) 799 goto err_reset_mode; 800 } 801 802 error = usb_submit_urb(dev->tp_urb, GFP_KERNEL); 803 if (error) 804 goto err_kill_bt; 805 806 return 0; 807 808 err_kill_bt: 809 usb_kill_urb(dev->bt_urb); 810 err_reset_mode: 811 bcm5974_wellspring_mode(dev, false); 812 err_out: 813 return error; 814 } 815 816 static void bcm5974_pause_traffic(struct bcm5974 *dev) 817 { 818 usb_kill_urb(dev->tp_urb); 819 usb_kill_urb(dev->bt_urb); 820 bcm5974_wellspring_mode(dev, false); 821 } 822 823 /* 824 * The code below implements open/close and manual suspend/resume. 825 * All functions may be called in random order. 826 * 827 * Opening a suspended device fails with EACCES - permission denied. 828 * 829 * Failing a resume leaves the device resumed but closed. 830 */ 831 static int bcm5974_open(struct input_dev *input) 832 { 833 struct bcm5974 *dev = input_get_drvdata(input); 834 int error; 835 836 error = usb_autopm_get_interface(dev->intf); 837 if (error) 838 return error; 839 840 mutex_lock(&dev->pm_mutex); 841 842 error = bcm5974_start_traffic(dev); 843 if (!error) 844 dev->opened = 1; 845 846 mutex_unlock(&dev->pm_mutex); 847 848 if (error) 849 usb_autopm_put_interface(dev->intf); 850 851 return error; 852 } 853 854 static void bcm5974_close(struct input_dev *input) 855 { 856 struct bcm5974 *dev = input_get_drvdata(input); 857 858 mutex_lock(&dev->pm_mutex); 859 860 bcm5974_pause_traffic(dev); 861 dev->opened = 0; 862 863 mutex_unlock(&dev->pm_mutex); 864 865 usb_autopm_put_interface(dev->intf); 866 } 867 868 static int bcm5974_suspend(struct usb_interface *iface, pm_message_t message) 869 { 870 struct bcm5974 *dev = usb_get_intfdata(iface); 871 872 mutex_lock(&dev->pm_mutex); 873 874 if (dev->opened) 875 bcm5974_pause_traffic(dev); 876 877 mutex_unlock(&dev->pm_mutex); 878 879 return 0; 880 } 881 882 static int bcm5974_resume(struct usb_interface *iface) 883 { 884 struct bcm5974 *dev = usb_get_intfdata(iface); 885 int error = 0; 886 887 mutex_lock(&dev->pm_mutex); 888 889 if (dev->opened) 890 error = bcm5974_start_traffic(dev); 891 892 mutex_unlock(&dev->pm_mutex); 893 894 return error; 895 } 896 897 static bool bcm5974_check_endpoints(struct usb_interface *iface, 898 const struct bcm5974_config *cfg) 899 { 900 u8 ep_addr[MAX_ENDPOINTS + 1] = {0}; 901 902 ep_addr[0] = cfg->tp_ep; 903 if (cfg->tp_type == TYPE1) 904 ep_addr[1] = cfg->bt_ep; 905 906 return usb_check_int_endpoints(iface, ep_addr); 907 } 908 909 static int bcm5974_probe(struct usb_interface *iface, 910 const struct usb_device_id *id) 911 { 912 struct usb_device *udev = interface_to_usbdev(iface); 913 const struct bcm5974_config *cfg; 914 struct bcm5974 *dev; 915 struct input_dev *input_dev; 916 int error = -ENOMEM; 917 918 /* find the product index */ 919 cfg = bcm5974_get_config(udev); 920 921 if (!bcm5974_check_endpoints(iface, cfg)) { 922 dev_err(&iface->dev, "Unexpected non-int endpoint\n"); 923 return -ENODEV; 924 } 925 926 /* allocate memory for our device state and initialize it */ 927 dev = kzalloc(sizeof(struct bcm5974), GFP_KERNEL); 928 input_dev = input_allocate_device(); 929 if (!dev || !input_dev) { 930 dev_err(&iface->dev, "out of memory\n"); 931 goto err_free_devs; 932 } 933 934 dev->udev = udev; 935 dev->intf = iface; 936 dev->input = input_dev; 937 dev->cfg = *cfg; 938 mutex_init(&dev->pm_mutex); 939 940 /* setup urbs */ 941 if (cfg->tp_type == TYPE1) { 942 dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL); 943 if (!dev->bt_urb) 944 goto err_free_devs; 945 } 946 947 dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL); 948 if (!dev->tp_urb) 949 goto err_free_bt_urb; 950 951 if (dev->bt_urb) { 952 dev->bt_data = usb_alloc_coherent(dev->udev, 953 dev->cfg.bt_datalen, GFP_KERNEL, 954 &dev->bt_urb->transfer_dma); 955 if (!dev->bt_data) 956 goto err_free_urb; 957 } 958 959 dev->tp_data = usb_alloc_coherent(dev->udev, 960 dev->cfg.tp_datalen, GFP_KERNEL, 961 &dev->tp_urb->transfer_dma); 962 if (!dev->tp_data) 963 goto err_free_bt_buffer; 964 965 if (dev->bt_urb) { 966 usb_fill_int_urb(dev->bt_urb, udev, 967 usb_rcvintpipe(udev, cfg->bt_ep), 968 dev->bt_data, dev->cfg.bt_datalen, 969 bcm5974_irq_button, dev, 1); 970 971 dev->bt_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 972 } 973 974 usb_fill_int_urb(dev->tp_urb, udev, 975 usb_rcvintpipe(udev, cfg->tp_ep), 976 dev->tp_data, dev->cfg.tp_datalen, 977 bcm5974_irq_trackpad, dev, 1); 978 979 dev->tp_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 980 981 /* create bcm5974 device */ 982 usb_make_path(udev, dev->phys, sizeof(dev->phys)); 983 strlcat(dev->phys, "/input0", sizeof(dev->phys)); 984 985 input_dev->name = "bcm5974"; 986 input_dev->phys = dev->phys; 987 usb_to_input_id(dev->udev, &input_dev->id); 988 /* report driver capabilities via the version field */ 989 input_dev->id.version = cfg->caps; 990 input_dev->dev.parent = &iface->dev; 991 992 input_set_drvdata(input_dev, dev); 993 994 input_dev->open = bcm5974_open; 995 input_dev->close = bcm5974_close; 996 997 setup_events_to_report(input_dev, cfg); 998 999 error = input_register_device(dev->input); 1000 if (error) 1001 goto err_free_buffer; 1002 1003 /* save our data pointer in this interface device */ 1004 usb_set_intfdata(iface, dev); 1005 1006 return 0; 1007 1008 err_free_buffer: 1009 usb_free_coherent(dev->udev, dev->cfg.tp_datalen, 1010 dev->tp_data, dev->tp_urb->transfer_dma); 1011 err_free_bt_buffer: 1012 if (dev->bt_urb) 1013 usb_free_coherent(dev->udev, dev->cfg.bt_datalen, 1014 dev->bt_data, dev->bt_urb->transfer_dma); 1015 err_free_urb: 1016 usb_free_urb(dev->tp_urb); 1017 err_free_bt_urb: 1018 usb_free_urb(dev->bt_urb); 1019 err_free_devs: 1020 usb_set_intfdata(iface, NULL); 1021 input_free_device(input_dev); 1022 kfree(dev); 1023 return error; 1024 } 1025 1026 static void bcm5974_disconnect(struct usb_interface *iface) 1027 { 1028 struct bcm5974 *dev = usb_get_intfdata(iface); 1029 1030 usb_set_intfdata(iface, NULL); 1031 1032 input_unregister_device(dev->input); 1033 usb_free_coherent(dev->udev, dev->cfg.tp_datalen, 1034 dev->tp_data, dev->tp_urb->transfer_dma); 1035 if (dev->bt_urb) 1036 usb_free_coherent(dev->udev, dev->cfg.bt_datalen, 1037 dev->bt_data, dev->bt_urb->transfer_dma); 1038 usb_free_urb(dev->tp_urb); 1039 usb_free_urb(dev->bt_urb); 1040 kfree(dev); 1041 } 1042 1043 static struct usb_driver bcm5974_driver = { 1044 .name = "bcm5974", 1045 .probe = bcm5974_probe, 1046 .disconnect = bcm5974_disconnect, 1047 .suspend = bcm5974_suspend, 1048 .resume = bcm5974_resume, 1049 .id_table = bcm5974_table, 1050 .supports_autosuspend = 1, 1051 }; 1052 1053 module_usb_driver(bcm5974_driver); 1054