0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <linux/kernel.h>
0023 #include <linux/errno.h>
0024 #include <linux/slab.h>
0025 #include <linux/module.h>
0026 #include <linux/usb/input.h>
0027 #include <linux/hid.h>
0028 #include <linux/mutex.h>
0029 #include <linux/input/mt.h>
0030
0031 #define USB_VENDOR_ID_APPLE 0x05ac
0032
0033
0034 #define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223
0035 #define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224
0036 #define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225
0037
0038 #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
0039 #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
0040 #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
0041
0042 #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236
0043 #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237
0044 #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238
0045
0046 #define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f
0047 #define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240
0048 #define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241
0049
0050 #define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242
0051 #define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243
0052 #define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244
0053
0054 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245
0055 #define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246
0056 #define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247
0057
0058 #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249
0059 #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a
0060 #define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b
0061
0062 #define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI 0x024c
0063 #define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO 0x024d
0064 #define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS 0x024e
0065
0066 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252
0067 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253
0068 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254
0069
0070 #define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262
0071 #define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263
0072 #define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264
0073
0074 #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259
0075 #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a
0076 #define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b
0077
0078 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290
0079 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291
0080 #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292
0081
0082 #define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272
0083 #define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273
0084 #define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274
0085
0086 #define BCM5974_DEVICE(prod) { \
0087 .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \
0088 USB_DEVICE_ID_MATCH_INT_CLASS | \
0089 USB_DEVICE_ID_MATCH_INT_PROTOCOL), \
0090 .idVendor = USB_VENDOR_ID_APPLE, \
0091 .idProduct = (prod), \
0092 .bInterfaceClass = USB_INTERFACE_CLASS_HID, \
0093 .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE \
0094 }
0095
0096
0097 static const struct usb_device_id bcm5974_table[] = {
0098
0099 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
0100 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
0101 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_JIS),
0102
0103 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
0104 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
0105 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
0106
0107 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),
0108 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),
0109 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
0110
0111 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI),
0112 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ISO),
0113 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_JIS),
0114
0115 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI),
0116 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO),
0117 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS),
0118
0119 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI),
0120 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_ISO),
0121 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_JIS),
0122
0123 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI),
0124 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO),
0125 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS),
0126
0127 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI),
0128 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6_ISO),
0129 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6_JIS),
0130
0131 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI),
0132 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO),
0133 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS),
0134
0135 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI),
0136 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ISO),
0137 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_JIS),
0138
0139 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI),
0140 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO),
0141 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS),
0142
0143 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI),
0144 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ISO),
0145 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_JIS),
0146
0147 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI),
0148 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_ISO),
0149 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_JIS),
0150
0151 {}
0152 };
0153 MODULE_DEVICE_TABLE(usb, bcm5974_table);
0154
0155 MODULE_AUTHOR("Henrik Rydberg");
0156 MODULE_DESCRIPTION("Apple USB BCM5974 multitouch driver");
0157 MODULE_LICENSE("GPL");
0158
0159 #define dprintk(level, format, a...)\
0160 { if (debug >= level) printk(KERN_DEBUG format, ##a); }
0161
0162 static int debug = 1;
0163 module_param(debug, int, 0644);
0164 MODULE_PARM_DESC(debug, "Activate debugging output");
0165
0166
0167 struct bt_data {
0168 u8 unknown1;
0169 u8 button;
0170 u8 rel_x;
0171 u8 rel_y;
0172 };
0173
0174
0175 enum tp_type {
0176 TYPE1,
0177 TYPE2,
0178 TYPE3,
0179 TYPE4
0180 };
0181
0182
0183 #define HEADER_TYPE1 (13 * sizeof(__le16))
0184 #define HEADER_TYPE2 (15 * sizeof(__le16))
0185 #define HEADER_TYPE3 (19 * sizeof(__le16))
0186 #define HEADER_TYPE4 (23 * sizeof(__le16))
0187
0188
0189 #define BUTTON_TYPE1 0
0190 #define BUTTON_TYPE2 15
0191 #define BUTTON_TYPE3 23
0192 #define BUTTON_TYPE4 31
0193
0194
0195 #define HAS_INTEGRATED_BUTTON 1
0196
0197
0198 #define FSIZE_TYPE1 (14 * sizeof(__le16))
0199 #define FSIZE_TYPE2 (14 * sizeof(__le16))
0200 #define FSIZE_TYPE3 (14 * sizeof(__le16))
0201 #define FSIZE_TYPE4 (15 * sizeof(__le16))
0202
0203
0204 #define DELTA_TYPE1 (0 * sizeof(__le16))
0205 #define DELTA_TYPE2 (0 * sizeof(__le16))
0206 #define DELTA_TYPE3 (0 * sizeof(__le16))
0207 #define DELTA_TYPE4 (1 * sizeof(__le16))
0208
0209
0210 #define USBMSG_TYPE1 8, 0x300, 0, 0, 0x1, 0x8
0211 #define USBMSG_TYPE2 8, 0x300, 0, 0, 0x1, 0x8
0212 #define USBMSG_TYPE3 8, 0x300, 0, 0, 0x1, 0x8
0213 #define USBMSG_TYPE4 2, 0x302, 2, 1, 0x1, 0x0
0214
0215
0216 #define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID 1
0217 #define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID 9
0218
0219
0220 struct tp_finger {
0221 __le16 origin;
0222 __le16 abs_x;
0223 __le16 abs_y;
0224 __le16 rel_x;
0225 __le16 rel_y;
0226 __le16 tool_major;
0227 __le16 tool_minor;
0228 __le16 orientation;
0229 __le16 touch_major;
0230 __le16 touch_minor;
0231 __le16 unused[2];
0232 __le16 pressure;
0233 __le16 multi;
0234 } __attribute__((packed,aligned(2)));
0235
0236
0237 #define MAX_FINGERS 16
0238 #define MAX_FINGER_ORIENTATION 16384
0239
0240
0241 struct bcm5974_param {
0242 int snratio;
0243 int min;
0244 int max;
0245 };
0246
0247
0248 struct bcm5974_config {
0249 int ansi, iso, jis;
0250 int caps;
0251 int bt_ep;
0252 int bt_datalen;
0253 int tp_ep;
0254 enum tp_type tp_type;
0255 int tp_header;
0256 int tp_datalen;
0257 int tp_button;
0258 int tp_fsize;
0259 int tp_delta;
0260 int um_size;
0261 int um_req_val;
0262 int um_req_idx;
0263 int um_switch_idx;
0264 int um_switch_on;
0265 int um_switch_off;
0266 struct bcm5974_param p;
0267 struct bcm5974_param w;
0268 struct bcm5974_param x;
0269 struct bcm5974_param y;
0270 struct bcm5974_param o;
0271 };
0272
0273
0274 struct bcm5974 {
0275 char phys[64];
0276 struct usb_device *udev;
0277 struct usb_interface *intf;
0278 struct input_dev *input;
0279 struct bcm5974_config cfg;
0280 struct mutex pm_mutex;
0281 int opened;
0282 struct urb *bt_urb;
0283 struct bt_data *bt_data;
0284 struct urb *tp_urb;
0285 u8 *tp_data;
0286 const struct tp_finger *index[MAX_FINGERS];
0287 struct input_mt_pos pos[MAX_FINGERS];
0288 int slots[MAX_FINGERS];
0289 };
0290
0291
0292 static const struct tp_finger *get_tp_finger(const struct bcm5974 *dev, int i)
0293 {
0294 const struct bcm5974_config *c = &dev->cfg;
0295 u8 *f_base = dev->tp_data + c->tp_header + c->tp_delta;
0296
0297 return (const struct tp_finger *)(f_base + i * c->tp_fsize);
0298 }
0299
0300 #define DATAFORMAT(type) \
0301 type, \
0302 HEADER_##type, \
0303 HEADER_##type + (MAX_FINGERS) * (FSIZE_##type), \
0304 BUTTON_##type, \
0305 FSIZE_##type, \
0306 DELTA_##type, \
0307 USBMSG_##type
0308
0309
0310 #define SN_PRESSURE 45
0311 #define SN_WIDTH 25
0312 #define SN_COORD 250
0313 #define SN_ORIENT 10
0314
0315
0316 static const struct bcm5974_config bcm5974_config_table[] = {
0317 {
0318 USB_DEVICE_ID_APPLE_WELLSPRING_ANSI,
0319 USB_DEVICE_ID_APPLE_WELLSPRING_ISO,
0320 USB_DEVICE_ID_APPLE_WELLSPRING_JIS,
0321 0,
0322 0x84, sizeof(struct bt_data),
0323 0x81, DATAFORMAT(TYPE1),
0324 { SN_PRESSURE, 0, 256 },
0325 { SN_WIDTH, 0, 2048 },
0326 { SN_COORD, -4824, 5342 },
0327 { SN_COORD, -172, 5820 },
0328 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
0329 },
0330 {
0331 USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI,
0332 USB_DEVICE_ID_APPLE_WELLSPRING2_ISO,
0333 USB_DEVICE_ID_APPLE_WELLSPRING2_JIS,
0334 0,
0335 0x84, sizeof(struct bt_data),
0336 0x81, DATAFORMAT(TYPE1),
0337 { SN_PRESSURE, 0, 256 },
0338 { SN_WIDTH, 0, 2048 },
0339 { SN_COORD, -4824, 4824 },
0340 { SN_COORD, -172, 4290 },
0341 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
0342 },
0343 {
0344 USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI,
0345 USB_DEVICE_ID_APPLE_WELLSPRING3_ISO,
0346 USB_DEVICE_ID_APPLE_WELLSPRING3_JIS,
0347 HAS_INTEGRATED_BUTTON,
0348 0x84, sizeof(struct bt_data),
0349 0x81, DATAFORMAT(TYPE2),
0350 { SN_PRESSURE, 0, 300 },
0351 { SN_WIDTH, 0, 2048 },
0352 { SN_COORD, -4460, 5166 },
0353 { SN_COORD, -75, 6700 },
0354 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
0355 },
0356 {
0357 USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI,
0358 USB_DEVICE_ID_APPLE_WELLSPRING4_ISO,
0359 USB_DEVICE_ID_APPLE_WELLSPRING4_JIS,
0360 HAS_INTEGRATED_BUTTON,
0361 0x84, sizeof(struct bt_data),
0362 0x81, DATAFORMAT(TYPE2),
0363 { SN_PRESSURE, 0, 300 },
0364 { SN_WIDTH, 0, 2048 },
0365 { SN_COORD, -4620, 5140 },
0366 { SN_COORD, -150, 6600 },
0367 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
0368 },
0369 {
0370 USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI,
0371 USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO,
0372 USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS,
0373 HAS_INTEGRATED_BUTTON,
0374 0x84, sizeof(struct bt_data),
0375 0x81, DATAFORMAT(TYPE2),
0376 { SN_PRESSURE, 0, 300 },
0377 { SN_WIDTH, 0, 2048 },
0378 { SN_COORD, -4616, 5112 },
0379 { SN_COORD, -142, 5234 },
0380 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
0381 },
0382 {
0383 USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI,
0384 USB_DEVICE_ID_APPLE_WELLSPRING5_ISO,
0385 USB_DEVICE_ID_APPLE_WELLSPRING5_JIS,
0386 HAS_INTEGRATED_BUTTON,
0387 0x84, sizeof(struct bt_data),
0388 0x81, DATAFORMAT(TYPE2),
0389 { SN_PRESSURE, 0, 300 },
0390 { SN_WIDTH, 0, 2048 },
0391 { SN_COORD, -4415, 5050 },
0392 { SN_COORD, -55, 6680 },
0393 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
0394 },
0395 {
0396 USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI,
0397 USB_DEVICE_ID_APPLE_WELLSPRING6_ISO,
0398 USB_DEVICE_ID_APPLE_WELLSPRING6_JIS,
0399 HAS_INTEGRATED_BUTTON,
0400 0x84, sizeof(struct bt_data),
0401 0x81, DATAFORMAT(TYPE2),
0402 { SN_PRESSURE, 0, 300 },
0403 { SN_WIDTH, 0, 2048 },
0404 { SN_COORD, -4620, 5140 },
0405 { SN_COORD, -150, 6600 },
0406 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
0407 },
0408 {
0409 USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI,
0410 USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO,
0411 USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS,
0412 HAS_INTEGRATED_BUTTON,
0413 0x84, sizeof(struct bt_data),
0414 0x81, DATAFORMAT(TYPE2),
0415 { SN_PRESSURE, 0, 300 },
0416 { SN_WIDTH, 0, 2048 },
0417 { SN_COORD, -4750, 5280 },
0418 { SN_COORD, -150, 6730 },
0419 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
0420 },
0421 {
0422 USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI,
0423 USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO,
0424 USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS,
0425 HAS_INTEGRATED_BUTTON,
0426 0x84, sizeof(struct bt_data),
0427 0x81, DATAFORMAT(TYPE2),
0428 { SN_PRESSURE, 0, 300 },
0429 { SN_WIDTH, 0, 2048 },
0430 { SN_COORD, -4620, 5140 },
0431 { SN_COORD, -150, 6600 },
0432 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
0433 },
0434 {
0435 USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI,
0436 USB_DEVICE_ID_APPLE_WELLSPRING7_ISO,
0437 USB_DEVICE_ID_APPLE_WELLSPRING7_JIS,
0438 HAS_INTEGRATED_BUTTON,
0439 0x84, sizeof(struct bt_data),
0440 0x81, DATAFORMAT(TYPE2),
0441 { SN_PRESSURE, 0, 300 },
0442 { SN_WIDTH, 0, 2048 },
0443 { SN_COORD, -4750, 5280 },
0444 { SN_COORD, -150, 6730 },
0445 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
0446 },
0447 {
0448 USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI,
0449 USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO,
0450 USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS,
0451 HAS_INTEGRATED_BUTTON,
0452 0x84, sizeof(struct bt_data),
0453 0x81, DATAFORMAT(TYPE2),
0454 { SN_PRESSURE, 0, 300 },
0455 { SN_WIDTH, 0, 2048 },
0456 { SN_COORD, -4750, 5280 },
0457 { SN_COORD, -150, 6730 },
0458 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
0459 },
0460 {
0461 USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI,
0462 USB_DEVICE_ID_APPLE_WELLSPRING8_ISO,
0463 USB_DEVICE_ID_APPLE_WELLSPRING8_JIS,
0464 HAS_INTEGRATED_BUTTON,
0465 0, sizeof(struct bt_data),
0466 0x83, DATAFORMAT(TYPE3),
0467 { SN_PRESSURE, 0, 300 },
0468 { SN_WIDTH, 0, 2048 },
0469 { SN_COORD, -4620, 5140 },
0470 { SN_COORD, -150, 6600 },
0471 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
0472 },
0473 {
0474 USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI,
0475 USB_DEVICE_ID_APPLE_WELLSPRING9_ISO,
0476 USB_DEVICE_ID_APPLE_WELLSPRING9_JIS,
0477 HAS_INTEGRATED_BUTTON,
0478 0, sizeof(struct bt_data),
0479 0x83, DATAFORMAT(TYPE4),
0480 { SN_PRESSURE, 0, 300 },
0481 { SN_WIDTH, 0, 2048 },
0482 { SN_COORD, -4828, 5345 },
0483 { SN_COORD, -203, 6803 },
0484 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
0485 },
0486 {}
0487 };
0488
0489
0490 static const struct bcm5974_config *bcm5974_get_config(struct usb_device *udev)
0491 {
0492 u16 id = le16_to_cpu(udev->descriptor.idProduct);
0493 const struct bcm5974_config *cfg;
0494
0495 for (cfg = bcm5974_config_table; cfg->ansi; ++cfg)
0496 if (cfg->ansi == id || cfg->iso == id || cfg->jis == id)
0497 return cfg;
0498
0499 return bcm5974_config_table;
0500 }
0501
0502
0503 static inline int raw2int(__le16 x)
0504 {
0505 return (signed short)le16_to_cpu(x);
0506 }
0507
0508 static void set_abs(struct input_dev *input, unsigned int code,
0509 const struct bcm5974_param *p)
0510 {
0511 int fuzz = p->snratio ? (p->max - p->min) / p->snratio : 0;
0512 input_set_abs_params(input, code, p->min, p->max, fuzz, 0);
0513 }
0514
0515
0516 static void setup_events_to_report(struct input_dev *input_dev,
0517 const struct bcm5974_config *cfg)
0518 {
0519 __set_bit(EV_ABS, input_dev->evbit);
0520
0521
0522 input_set_abs_params(input_dev, ABS_PRESSURE, 0, 256, 5, 0);
0523 input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 16, 0, 0);
0524
0525
0526 set_abs(input_dev, ABS_MT_TOUCH_MAJOR, &cfg->w);
0527 set_abs(input_dev, ABS_MT_TOUCH_MINOR, &cfg->w);
0528
0529 set_abs(input_dev, ABS_MT_WIDTH_MAJOR, &cfg->w);
0530 set_abs(input_dev, ABS_MT_WIDTH_MINOR, &cfg->w);
0531
0532 set_abs(input_dev, ABS_MT_ORIENTATION, &cfg->o);
0533
0534 set_abs(input_dev, ABS_MT_POSITION_X, &cfg->x);
0535 set_abs(input_dev, ABS_MT_POSITION_Y, &cfg->y);
0536
0537 __set_bit(EV_KEY, input_dev->evbit);
0538 __set_bit(BTN_LEFT, input_dev->keybit);
0539
0540 if (cfg->caps & HAS_INTEGRATED_BUTTON)
0541 __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
0542
0543 input_mt_init_slots(input_dev, MAX_FINGERS,
0544 INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK);
0545 }
0546
0547
0548 static int report_bt_state(struct bcm5974 *dev, int size)
0549 {
0550 if (size != sizeof(struct bt_data))
0551 return -EIO;
0552
0553 dprintk(7,
0554 "bcm5974: button data: %x %x %x %x\n",
0555 dev->bt_data->unknown1, dev->bt_data->button,
0556 dev->bt_data->rel_x, dev->bt_data->rel_y);
0557
0558 input_report_key(dev->input, BTN_LEFT, dev->bt_data->button);
0559 input_sync(dev->input);
0560
0561 return 0;
0562 }
0563
0564 static void report_finger_data(struct input_dev *input, int slot,
0565 const struct input_mt_pos *pos,
0566 const struct tp_finger *f)
0567 {
0568 input_mt_slot(input, slot);
0569 input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
0570
0571 input_report_abs(input, ABS_MT_TOUCH_MAJOR,
0572 raw2int(f->touch_major) << 1);
0573 input_report_abs(input, ABS_MT_TOUCH_MINOR,
0574 raw2int(f->touch_minor) << 1);
0575 input_report_abs(input, ABS_MT_WIDTH_MAJOR,
0576 raw2int(f->tool_major) << 1);
0577 input_report_abs(input, ABS_MT_WIDTH_MINOR,
0578 raw2int(f->tool_minor) << 1);
0579 input_report_abs(input, ABS_MT_ORIENTATION,
0580 MAX_FINGER_ORIENTATION - raw2int(f->orientation));
0581 input_report_abs(input, ABS_MT_POSITION_X, pos->x);
0582 input_report_abs(input, ABS_MT_POSITION_Y, pos->y);
0583 }
0584
0585 static void report_synaptics_data(struct input_dev *input,
0586 const struct bcm5974_config *cfg,
0587 const struct tp_finger *f, int raw_n)
0588 {
0589 int abs_p = 0, abs_w = 0;
0590
0591 if (raw_n) {
0592 int p = raw2int(f->touch_major);
0593 int w = raw2int(f->tool_major);
0594 if (p > 0 && raw2int(f->origin)) {
0595 abs_p = clamp_val(256 * p / cfg->p.max, 0, 255);
0596 abs_w = clamp_val(16 * w / cfg->w.max, 0, 15);
0597 }
0598 }
0599
0600 input_report_abs(input, ABS_PRESSURE, abs_p);
0601 input_report_abs(input, ABS_TOOL_WIDTH, abs_w);
0602 }
0603
0604
0605 static int report_tp_state(struct bcm5974 *dev, int size)
0606 {
0607 const struct bcm5974_config *c = &dev->cfg;
0608 const struct tp_finger *f;
0609 struct input_dev *input = dev->input;
0610 int raw_n, i, n = 0;
0611
0612 if (size < c->tp_header || (size - c->tp_header) % c->tp_fsize != 0)
0613 return -EIO;
0614
0615 raw_n = (size - c->tp_header) / c->tp_fsize;
0616
0617 for (i = 0; i < raw_n; i++) {
0618 f = get_tp_finger(dev, i);
0619 if (raw2int(f->touch_major) == 0)
0620 continue;
0621 dev->pos[n].x = raw2int(f->abs_x);
0622 dev->pos[n].y = c->y.min + c->y.max - raw2int(f->abs_y);
0623 dev->index[n++] = f;
0624 }
0625
0626 input_mt_assign_slots(input, dev->slots, dev->pos, n, 0);
0627
0628 for (i = 0; i < n; i++)
0629 report_finger_data(input, dev->slots[i],
0630 &dev->pos[i], dev->index[i]);
0631
0632 input_mt_sync_frame(input);
0633
0634 report_synaptics_data(input, c, get_tp_finger(dev, 0), raw_n);
0635
0636
0637 if (c->caps & HAS_INTEGRATED_BUTTON) {
0638 int ibt = raw2int(dev->tp_data[c->tp_button]);
0639 input_report_key(input, BTN_LEFT, ibt);
0640 }
0641
0642 input_sync(input);
0643
0644 return 0;
0645 }
0646
0647 static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on)
0648 {
0649 const struct bcm5974_config *c = &dev->cfg;
0650 int retval = 0, size;
0651 char *data;
0652
0653
0654 if (c->tp_type == TYPE3)
0655 return 0;
0656
0657 data = kmalloc(c->um_size, GFP_KERNEL);
0658 if (!data) {
0659 dev_err(&dev->intf->dev, "out of memory\n");
0660 retval = -ENOMEM;
0661 goto out;
0662 }
0663
0664
0665 size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
0666 BCM5974_WELLSPRING_MODE_READ_REQUEST_ID,
0667 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0668 c->um_req_val, c->um_req_idx, data, c->um_size, 5000);
0669
0670 if (size != c->um_size) {
0671 dev_err(&dev->intf->dev, "could not read from device\n");
0672 retval = -EIO;
0673 goto out;
0674 }
0675
0676
0677 data[c->um_switch_idx] = on ? c->um_switch_on : c->um_switch_off;
0678
0679
0680 size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
0681 BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID,
0682 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
0683 c->um_req_val, c->um_req_idx, data, c->um_size, 5000);
0684
0685 if (size != c->um_size) {
0686 dev_err(&dev->intf->dev, "could not write to device\n");
0687 retval = -EIO;
0688 goto out;
0689 }
0690
0691 dprintk(2, "bcm5974: switched to %s mode.\n",
0692 on ? "wellspring" : "normal");
0693
0694 out:
0695 kfree(data);
0696 return retval;
0697 }
0698
0699 static void bcm5974_irq_button(struct urb *urb)
0700 {
0701 struct bcm5974 *dev = urb->context;
0702 struct usb_interface *intf = dev->intf;
0703 int error;
0704
0705 switch (urb->status) {
0706 case 0:
0707 break;
0708 case -EOVERFLOW:
0709 case -ECONNRESET:
0710 case -ENOENT:
0711 case -ESHUTDOWN:
0712 dev_dbg(&intf->dev, "button urb shutting down: %d\n",
0713 urb->status);
0714 return;
0715 default:
0716 dev_dbg(&intf->dev, "button urb status: %d\n", urb->status);
0717 goto exit;
0718 }
0719
0720 if (report_bt_state(dev, dev->bt_urb->actual_length))
0721 dprintk(1, "bcm5974: bad button package, length: %d\n",
0722 dev->bt_urb->actual_length);
0723
0724 exit:
0725 error = usb_submit_urb(dev->bt_urb, GFP_ATOMIC);
0726 if (error)
0727 dev_err(&intf->dev, "button urb failed: %d\n", error);
0728 }
0729
0730 static void bcm5974_irq_trackpad(struct urb *urb)
0731 {
0732 struct bcm5974 *dev = urb->context;
0733 struct usb_interface *intf = dev->intf;
0734 int error;
0735
0736 switch (urb->status) {
0737 case 0:
0738 break;
0739 case -EOVERFLOW:
0740 case -ECONNRESET:
0741 case -ENOENT:
0742 case -ESHUTDOWN:
0743 dev_dbg(&intf->dev, "trackpad urb shutting down: %d\n",
0744 urb->status);
0745 return;
0746 default:
0747 dev_dbg(&intf->dev, "trackpad urb status: %d\n", urb->status);
0748 goto exit;
0749 }
0750
0751
0752 if (dev->tp_urb->actual_length == 2)
0753 goto exit;
0754
0755 if (report_tp_state(dev, dev->tp_urb->actual_length))
0756 dprintk(1, "bcm5974: bad trackpad package, length: %d\n",
0757 dev->tp_urb->actual_length);
0758
0759 exit:
0760 error = usb_submit_urb(dev->tp_urb, GFP_ATOMIC);
0761 if (error)
0762 dev_err(&intf->dev, "trackpad urb failed: %d\n", error);
0763 }
0764
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783 static int bcm5974_start_traffic(struct bcm5974 *dev)
0784 {
0785 int error;
0786
0787 error = bcm5974_wellspring_mode(dev, true);
0788 if (error) {
0789 dprintk(1, "bcm5974: mode switch failed\n");
0790 goto err_out;
0791 }
0792
0793 if (dev->bt_urb) {
0794 error = usb_submit_urb(dev->bt_urb, GFP_KERNEL);
0795 if (error)
0796 goto err_reset_mode;
0797 }
0798
0799 error = usb_submit_urb(dev->tp_urb, GFP_KERNEL);
0800 if (error)
0801 goto err_kill_bt;
0802
0803 return 0;
0804
0805 err_kill_bt:
0806 usb_kill_urb(dev->bt_urb);
0807 err_reset_mode:
0808 bcm5974_wellspring_mode(dev, false);
0809 err_out:
0810 return error;
0811 }
0812
0813 static void bcm5974_pause_traffic(struct bcm5974 *dev)
0814 {
0815 usb_kill_urb(dev->tp_urb);
0816 usb_kill_urb(dev->bt_urb);
0817 bcm5974_wellspring_mode(dev, false);
0818 }
0819
0820
0821
0822
0823
0824
0825
0826
0827
0828 static int bcm5974_open(struct input_dev *input)
0829 {
0830 struct bcm5974 *dev = input_get_drvdata(input);
0831 int error;
0832
0833 error = usb_autopm_get_interface(dev->intf);
0834 if (error)
0835 return error;
0836
0837 mutex_lock(&dev->pm_mutex);
0838
0839 error = bcm5974_start_traffic(dev);
0840 if (!error)
0841 dev->opened = 1;
0842
0843 mutex_unlock(&dev->pm_mutex);
0844
0845 if (error)
0846 usb_autopm_put_interface(dev->intf);
0847
0848 return error;
0849 }
0850
0851 static void bcm5974_close(struct input_dev *input)
0852 {
0853 struct bcm5974 *dev = input_get_drvdata(input);
0854
0855 mutex_lock(&dev->pm_mutex);
0856
0857 bcm5974_pause_traffic(dev);
0858 dev->opened = 0;
0859
0860 mutex_unlock(&dev->pm_mutex);
0861
0862 usb_autopm_put_interface(dev->intf);
0863 }
0864
0865 static int bcm5974_suspend(struct usb_interface *iface, pm_message_t message)
0866 {
0867 struct bcm5974 *dev = usb_get_intfdata(iface);
0868
0869 mutex_lock(&dev->pm_mutex);
0870
0871 if (dev->opened)
0872 bcm5974_pause_traffic(dev);
0873
0874 mutex_unlock(&dev->pm_mutex);
0875
0876 return 0;
0877 }
0878
0879 static int bcm5974_resume(struct usb_interface *iface)
0880 {
0881 struct bcm5974 *dev = usb_get_intfdata(iface);
0882 int error = 0;
0883
0884 mutex_lock(&dev->pm_mutex);
0885
0886 if (dev->opened)
0887 error = bcm5974_start_traffic(dev);
0888
0889 mutex_unlock(&dev->pm_mutex);
0890
0891 return error;
0892 }
0893
0894 static int bcm5974_probe(struct usb_interface *iface,
0895 const struct usb_device_id *id)
0896 {
0897 struct usb_device *udev = interface_to_usbdev(iface);
0898 const struct bcm5974_config *cfg;
0899 struct bcm5974 *dev;
0900 struct input_dev *input_dev;
0901 int error = -ENOMEM;
0902
0903
0904 cfg = bcm5974_get_config(udev);
0905
0906
0907 dev = kzalloc(sizeof(struct bcm5974), GFP_KERNEL);
0908 input_dev = input_allocate_device();
0909 if (!dev || !input_dev) {
0910 dev_err(&iface->dev, "out of memory\n");
0911 goto err_free_devs;
0912 }
0913
0914 dev->udev = udev;
0915 dev->intf = iface;
0916 dev->input = input_dev;
0917 dev->cfg = *cfg;
0918 mutex_init(&dev->pm_mutex);
0919
0920
0921 if (cfg->tp_type == TYPE1) {
0922 dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL);
0923 if (!dev->bt_urb)
0924 goto err_free_devs;
0925 }
0926
0927 dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL);
0928 if (!dev->tp_urb)
0929 goto err_free_bt_urb;
0930
0931 if (dev->bt_urb) {
0932 dev->bt_data = usb_alloc_coherent(dev->udev,
0933 dev->cfg.bt_datalen, GFP_KERNEL,
0934 &dev->bt_urb->transfer_dma);
0935 if (!dev->bt_data)
0936 goto err_free_urb;
0937 }
0938
0939 dev->tp_data = usb_alloc_coherent(dev->udev,
0940 dev->cfg.tp_datalen, GFP_KERNEL,
0941 &dev->tp_urb->transfer_dma);
0942 if (!dev->tp_data)
0943 goto err_free_bt_buffer;
0944
0945 if (dev->bt_urb) {
0946 usb_fill_int_urb(dev->bt_urb, udev,
0947 usb_rcvintpipe(udev, cfg->bt_ep),
0948 dev->bt_data, dev->cfg.bt_datalen,
0949 bcm5974_irq_button, dev, 1);
0950
0951 dev->bt_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
0952 }
0953
0954 usb_fill_int_urb(dev->tp_urb, udev,
0955 usb_rcvintpipe(udev, cfg->tp_ep),
0956 dev->tp_data, dev->cfg.tp_datalen,
0957 bcm5974_irq_trackpad, dev, 1);
0958
0959 dev->tp_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
0960
0961
0962 usb_make_path(udev, dev->phys, sizeof(dev->phys));
0963 strlcat(dev->phys, "/input0", sizeof(dev->phys));
0964
0965 input_dev->name = "bcm5974";
0966 input_dev->phys = dev->phys;
0967 usb_to_input_id(dev->udev, &input_dev->id);
0968
0969 input_dev->id.version = cfg->caps;
0970 input_dev->dev.parent = &iface->dev;
0971
0972 input_set_drvdata(input_dev, dev);
0973
0974 input_dev->open = bcm5974_open;
0975 input_dev->close = bcm5974_close;
0976
0977 setup_events_to_report(input_dev, cfg);
0978
0979 error = input_register_device(dev->input);
0980 if (error)
0981 goto err_free_buffer;
0982
0983
0984 usb_set_intfdata(iface, dev);
0985
0986 return 0;
0987
0988 err_free_buffer:
0989 usb_free_coherent(dev->udev, dev->cfg.tp_datalen,
0990 dev->tp_data, dev->tp_urb->transfer_dma);
0991 err_free_bt_buffer:
0992 if (dev->bt_urb)
0993 usb_free_coherent(dev->udev, dev->cfg.bt_datalen,
0994 dev->bt_data, dev->bt_urb->transfer_dma);
0995 err_free_urb:
0996 usb_free_urb(dev->tp_urb);
0997 err_free_bt_urb:
0998 usb_free_urb(dev->bt_urb);
0999 err_free_devs:
1000 usb_set_intfdata(iface, NULL);
1001 input_free_device(input_dev);
1002 kfree(dev);
1003 return error;
1004 }
1005
1006 static void bcm5974_disconnect(struct usb_interface *iface)
1007 {
1008 struct bcm5974 *dev = usb_get_intfdata(iface);
1009
1010 usb_set_intfdata(iface, NULL);
1011
1012 input_unregister_device(dev->input);
1013 usb_free_coherent(dev->udev, dev->cfg.tp_datalen,
1014 dev->tp_data, dev->tp_urb->transfer_dma);
1015 if (dev->bt_urb)
1016 usb_free_coherent(dev->udev, dev->cfg.bt_datalen,
1017 dev->bt_data, dev->bt_urb->transfer_dma);
1018 usb_free_urb(dev->tp_urb);
1019 usb_free_urb(dev->bt_urb);
1020 kfree(dev);
1021 }
1022
1023 static struct usb_driver bcm5974_driver = {
1024 .name = "bcm5974",
1025 .probe = bcm5974_probe,
1026 .disconnect = bcm5974_disconnect,
1027 .suspend = bcm5974_suspend,
1028 .resume = bcm5974_resume,
1029 .id_table = bcm5974_table,
1030 .supports_autosuspend = 1,
1031 };
1032
1033 module_usb_driver(bcm5974_driver);