File Index
Files and directories
Sign in
FILE

bcm5974.c

File preview with syntax highlighting.

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