Version:  2.0.40 2.2.26 2.4.37 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2

Linux/drivers/input/mouse/bcm5974.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us