1064 lines · 31.9 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-or-later/* * Apple USB BCM5974 (Macbook Air and Penryn Macbook Pro) multitouch driver * * Copyright (C) 2008	   Henrik Rydberg (rydberg@euromail.se) * Copyright (C) 2015      John Horan (knasher@gmail.com) * * The USB initialization and package decoding was made by * Scott Shawcroft as part of the touchd user-space driver project: * Copyright (C) 2008	   Scott Shawcroft (scott.shawcroft@gmail.com) * * The BCM5974 driver is based on the appletouch driver: * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) * Copyright (C) 2005      Johannes Berg (johannes@sipsolutions.net) * Copyright (C) 2005	   Stelian Pop (stelian@popies.net) * Copyright (C) 2005	   Frank Arnold (frank@scirocco-5v-turbo.de) * Copyright (C) 2005	   Peter Osterlund (petero2@telia.com) * Copyright (C) 2005	   Michael Hanselmann (linux-kernel@hansmi.ch) * Copyright (C) 2006	   Nicolas Boichat (nicolas@boichat.ch) */ #include <linux/kernel.h>#include <linux/errno.h>#include <linux/slab.h>#include <linux/module.h>#include <linux/usb/input.h>#include <linux/hid.h>#include <linux/mutex.h>#include <linux/input/mt.h> #define USB_VENDOR_ID_APPLE		0x05ac /* MacbookAir, aka wellspring */#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI	0x0223#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO	0x0224#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS	0x0225/* MacbookProPenryn, aka wellspring2 */#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI	0x0230#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO	0x0231#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS	0x0232/* Macbook5,1 (unibody), aka wellspring3 */#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI	0x0236#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO	0x0237#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS	0x0238/* MacbookAir3,2 (unibody), aka wellspring5 */#define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI	0x023f#define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO	0x0240#define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS	0x0241/* MacbookAir3,1 (unibody), aka wellspring4 */#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI	0x0242#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO	0x0243#define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS	0x0244/* Macbook8 (unibody, March 2011) */#define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI	0x0245#define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO	0x0246#define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS	0x0247/* MacbookAir4,1 (unibody, July 2011) */#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI	0x0249#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO	0x024a#define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS	0x024b/* MacbookAir4,2 (unibody, July 2011) */#define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI	0x024c#define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO	0x024d#define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS	0x024e/* Macbook8,2 (unibody) */#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI	0x0252#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO	0x0253#define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS	0x0254/* MacbookPro10,1 (unibody, June 2012) */#define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI	0x0262#define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO	0x0263#define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS	0x0264/* MacbookPro10,2 (unibody, October 2012) */#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI	0x0259#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO	0x025a#define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS	0x025b/* MacbookAir6,2 (unibody, June 2013) */#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI	0x0290#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO	0x0291#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS	0x0292/* MacbookPro12,1 (2015) */#define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI	0x0272#define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO	0x0273#define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS	0x0274 #define BCM5974_DEVICE(prod) {					\	.match_flags = (USB_DEVICE_ID_MATCH_DEVICE |		\			USB_DEVICE_ID_MATCH_INT_CLASS |		\			USB_DEVICE_ID_MATCH_INT_PROTOCOL),	\	.idVendor = USB_VENDOR_ID_APPLE,			\	.idProduct = (prod),					\	.bInterfaceClass = USB_INTERFACE_CLASS_HID,		\	.bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE	\} /* table of devices that work with this driver */static const struct usb_device_id bcm5974_table[] = {	/* MacbookAir1.1 */	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ISO),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_JIS),	/* MacbookProPenryn */	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),	/* Macbook5,1 */	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),	/* MacbookAir3,2 */	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ISO),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_JIS),	/* MacbookAir3,1 */	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS),	/* MacbookPro8 */	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_ISO),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5_JIS),	/* MacbookAir4,1 */	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS),	/* MacbookAir4,2 */	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6_ISO),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING6_JIS),	/* MacbookPro8,2 */	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS),	/* MacbookPro10,1 */	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ISO),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_JIS),	/* MacbookPro10,2 */	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS),	/* MacbookAir6,2 */	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ISO),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_JIS),	/* MacbookPro12,1 */	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_ISO),	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_JIS),	/* Terminating entry */	{}};MODULE_DEVICE_TABLE(usb, bcm5974_table); MODULE_AUTHOR("Henrik Rydberg");MODULE_DESCRIPTION("Apple USB BCM5974 multitouch driver");MODULE_LICENSE("GPL"); #define dprintk(level, format, a...)\	{ if (debug >= level) printk(KERN_DEBUG format, ##a); } static int debug = 1;module_param(debug, int, 0644);MODULE_PARM_DESC(debug, "Activate debugging output"); /* button data structure */struct bt_data {	u8 unknown1;		/* constant */	u8 button;		/* left button */	u8 rel_x;		/* relative x coordinate */	u8 rel_y;		/* relative y coordinate */}; /* trackpad header types */enum tp_type {	TYPE1,			/* plain trackpad */	TYPE2,			/* button integrated in trackpad */	TYPE3,			/* additional header fields since June 2013 */	TYPE4			/* additional header field for pressure data */}; /* trackpad finger data offsets, le16-aligned */#define HEADER_TYPE1		(13 * sizeof(__le16))#define HEADER_TYPE2		(15 * sizeof(__le16))#define HEADER_TYPE3		(19 * sizeof(__le16))#define HEADER_TYPE4		(23 * sizeof(__le16)) /* trackpad button data offsets */#define BUTTON_TYPE1		0#define BUTTON_TYPE2		15#define BUTTON_TYPE3		23#define BUTTON_TYPE4		31 /* list of device capability bits */#define HAS_INTEGRATED_BUTTON	1 /* trackpad finger data block size */#define FSIZE_TYPE1		(14 * sizeof(__le16))#define FSIZE_TYPE2		(14 * sizeof(__le16))#define FSIZE_TYPE3		(14 * sizeof(__le16))#define FSIZE_TYPE4		(15 * sizeof(__le16)) /* offset from header to finger struct */#define DELTA_TYPE1		(0 * sizeof(__le16))#define DELTA_TYPE2		(0 * sizeof(__le16))#define DELTA_TYPE3		(0 * sizeof(__le16))#define DELTA_TYPE4		(1 * sizeof(__le16)) /* usb control message mode switch data */#define USBMSG_TYPE1		8, 0x300, 0, 0, 0x1, 0x8#define USBMSG_TYPE2		8, 0x300, 0, 0, 0x1, 0x8#define USBMSG_TYPE3		8, 0x300, 0, 0, 0x1, 0x8#define USBMSG_TYPE4		2, 0x302, 2, 1, 0x1, 0x0 /* Wellspring initialization constants */#define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID		1#define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID	9 /* trackpad finger structure, le16-aligned */struct tp_finger {	__le16 origin;		/* zero when switching track finger */	__le16 abs_x;		/* absolute x coodinate */	__le16 abs_y;		/* absolute y coodinate */	__le16 rel_x;		/* relative x coodinate */	__le16 rel_y;		/* relative y coodinate */	__le16 tool_major;	/* tool area, major axis */	__le16 tool_minor;	/* tool area, minor axis */	__le16 orientation;	/* 16384 when point, else 15 bit angle */	__le16 touch_major;	/* touch area, major axis */	__le16 touch_minor;	/* touch area, minor axis */	__le16 unused[2];	/* zeros */	__le16 pressure;	/* pressure on forcetouch touchpad */	__le16 multi;		/* one finger: varies, more fingers: constant */} __attribute__((packed,aligned(2))); /* trackpad finger data size, empirically at least ten fingers */#define MAX_FINGERS		16#define MAX_FINGER_ORIENTATION	16384 /* device-specific parameters */struct bcm5974_param {	int snratio;		/* signal-to-noise ratio */	int min;		/* device minimum reading */	int max;		/* device maximum reading */}; /* device-specific configuration */struct bcm5974_config {	int ansi, iso, jis;	/* the product id of this device */	int caps;		/* device capability bitmask */	int bt_ep;		/* the endpoint of the button interface */	int bt_datalen;		/* data length of the button interface */	int tp_ep;		/* the endpoint of the trackpad interface */	enum tp_type tp_type;	/* type of trackpad interface */	int tp_header;		/* bytes in header block */	int tp_datalen;		/* data length of the trackpad interface */	int tp_button;		/* offset to button data */	int tp_fsize;		/* bytes in single finger block */	int tp_delta;		/* offset from header to finger struct */	int um_size;		/* usb control message length */	int um_req_val;		/* usb control message value */	int um_req_idx;		/* usb control message index */	int um_switch_idx;	/* usb control message mode switch index */	int um_switch_on;	/* usb control message mode switch on */	int um_switch_off;	/* usb control message mode switch off */	struct bcm5974_param p;	/* finger pressure limits */	struct bcm5974_param w;	/* finger width limits */	struct bcm5974_param x;	/* horizontal limits */	struct bcm5974_param y;	/* vertical limits */	struct bcm5974_param o;	/* orientation limits */}; /* logical device structure */struct bcm5974 {	char phys[64];	struct usb_device *udev;	/* usb device */	struct usb_interface *intf;	/* our interface */	struct input_dev *input;	/* input dev */	struct bcm5974_config cfg;	/* device configuration */	struct mutex pm_mutex;		/* serialize access to open/suspend */	int opened;			/* 1: opened, 0: closed */	struct urb *bt_urb;		/* button usb request block */	struct bt_data *bt_data;	/* button transferred data */	struct urb *tp_urb;		/* trackpad usb request block */	u8 *tp_data;			/* trackpad transferred data */	const struct tp_finger *index[MAX_FINGERS];	/* finger index data */	struct input_mt_pos pos[MAX_FINGERS];		/* position array */	int slots[MAX_FINGERS];				/* slot assignments */	struct work_struct mode_reset_work;	unsigned long last_mode_reset;}; /* trackpad finger block data, le16-aligned */static const struct tp_finger *get_tp_finger(const struct bcm5974 *dev, int i){	const struct bcm5974_config *c = &dev->cfg;	u8 *f_base = dev->tp_data + c->tp_header + c->tp_delta; 	return (const struct tp_finger *)(f_base + i * c->tp_fsize);} #define DATAFORMAT(type)				\	type,						\	HEADER_##type,					\	HEADER_##type + (MAX_FINGERS) * (FSIZE_##type),	\	BUTTON_##type,					\	FSIZE_##type,					\	DELTA_##type,					\	USBMSG_##type /* logical signal quality */#define SN_PRESSURE	45		/* pressure signal-to-noise ratio */#define SN_WIDTH	25		/* width signal-to-noise ratio */#define SN_COORD	250		/* coordinate signal-to-noise ratio */#define SN_ORIENT	10		/* orientation signal-to-noise ratio */ /* device constants */static const struct bcm5974_config bcm5974_config_table[] = {	{		USB_DEVICE_ID_APPLE_WELLSPRING_ANSI,		USB_DEVICE_ID_APPLE_WELLSPRING_ISO,		USB_DEVICE_ID_APPLE_WELLSPRING_JIS,		0,		0x84, sizeof(struct bt_data),		0x81, DATAFORMAT(TYPE1),		{ SN_PRESSURE, 0, 256 },		{ SN_WIDTH, 0, 2048 },		{ SN_COORD, -4824, 5342 },		{ SN_COORD, -172, 5820 },		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }	},	{		USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI,		USB_DEVICE_ID_APPLE_WELLSPRING2_ISO,		USB_DEVICE_ID_APPLE_WELLSPRING2_JIS,		0,		0x84, sizeof(struct bt_data),		0x81, DATAFORMAT(TYPE1),		{ SN_PRESSURE, 0, 256 },		{ SN_WIDTH, 0, 2048 },		{ SN_COORD, -4824, 4824 },		{ SN_COORD, -172, 4290 },		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }	},	{		USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI,		USB_DEVICE_ID_APPLE_WELLSPRING3_ISO,		USB_DEVICE_ID_APPLE_WELLSPRING3_JIS,		HAS_INTEGRATED_BUTTON,		0x84, sizeof(struct bt_data),		0x81, DATAFORMAT(TYPE2),		{ SN_PRESSURE, 0, 300 },		{ SN_WIDTH, 0, 2048 },		{ SN_COORD, -4460, 5166 },		{ SN_COORD, -75, 6700 },		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }	},	{		USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI,		USB_DEVICE_ID_APPLE_WELLSPRING4_ISO,		USB_DEVICE_ID_APPLE_WELLSPRING4_JIS,		HAS_INTEGRATED_BUTTON,		0x84, sizeof(struct bt_data),		0x81, DATAFORMAT(TYPE2),		{ SN_PRESSURE, 0, 300 },		{ SN_WIDTH, 0, 2048 },		{ SN_COORD, -4620, 5140 },		{ SN_COORD, -150, 6600 },		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }	},	{		USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI,		USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO,		USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS,		HAS_INTEGRATED_BUTTON,		0x84, sizeof(struct bt_data),		0x81, DATAFORMAT(TYPE2),		{ SN_PRESSURE, 0, 300 },		{ SN_WIDTH, 0, 2048 },		{ SN_COORD, -4616, 5112 },		{ SN_COORD, -142, 5234 },		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }	},	{		USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI,		USB_DEVICE_ID_APPLE_WELLSPRING5_ISO,		USB_DEVICE_ID_APPLE_WELLSPRING5_JIS,		HAS_INTEGRATED_BUTTON,		0x84, sizeof(struct bt_data),		0x81, DATAFORMAT(TYPE2),		{ SN_PRESSURE, 0, 300 },		{ SN_WIDTH, 0, 2048 },		{ SN_COORD, -4415, 5050 },		{ SN_COORD, -55, 6680 },		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }	},	{		USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI,		USB_DEVICE_ID_APPLE_WELLSPRING6_ISO,		USB_DEVICE_ID_APPLE_WELLSPRING6_JIS,		HAS_INTEGRATED_BUTTON,		0x84, sizeof(struct bt_data),		0x81, DATAFORMAT(TYPE2),		{ SN_PRESSURE, 0, 300 },		{ SN_WIDTH, 0, 2048 },		{ SN_COORD, -4620, 5140 },		{ SN_COORD, -150, 6600 },		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }	},	{		USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI,		USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO,		USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS,		HAS_INTEGRATED_BUTTON,		0x84, sizeof(struct bt_data),		0x81, DATAFORMAT(TYPE2),		{ SN_PRESSURE, 0, 300 },		{ SN_WIDTH, 0, 2048 },		{ SN_COORD, -4750, 5280 },		{ SN_COORD, -150, 6730 },		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }	},	{		USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI,		USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO,		USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS,		HAS_INTEGRATED_BUTTON,		0x84, sizeof(struct bt_data),		0x81, DATAFORMAT(TYPE2),		{ SN_PRESSURE, 0, 300 },		{ SN_WIDTH, 0, 2048 },		{ SN_COORD, -4620, 5140 },		{ SN_COORD, -150, 6600 },		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }	},	{		USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI,		USB_DEVICE_ID_APPLE_WELLSPRING7_ISO,		USB_DEVICE_ID_APPLE_WELLSPRING7_JIS,		HAS_INTEGRATED_BUTTON,		0x84, sizeof(struct bt_data),		0x81, DATAFORMAT(TYPE2),		{ SN_PRESSURE, 0, 300 },		{ SN_WIDTH, 0, 2048 },		{ SN_COORD, -4750, 5280 },		{ SN_COORD, -150, 6730 },		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }	},	{		USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI,		USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO,		USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS,		HAS_INTEGRATED_BUTTON,		0x84, sizeof(struct bt_data),		0x81, DATAFORMAT(TYPE2),		{ SN_PRESSURE, 0, 300 },		{ SN_WIDTH, 0, 2048 },		{ SN_COORD, -4750, 5280 },		{ SN_COORD, -150, 6730 },		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }	},	{		USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI,		USB_DEVICE_ID_APPLE_WELLSPRING8_ISO,		USB_DEVICE_ID_APPLE_WELLSPRING8_JIS,		HAS_INTEGRATED_BUTTON,		0, sizeof(struct bt_data),		0x83, DATAFORMAT(TYPE3),		{ SN_PRESSURE, 0, 300 },		{ SN_WIDTH, 0, 2048 },		{ SN_COORD, -4620, 5140 },		{ SN_COORD, -150, 6600 },		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }	},	{		USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI,		USB_DEVICE_ID_APPLE_WELLSPRING9_ISO,		USB_DEVICE_ID_APPLE_WELLSPRING9_JIS,		HAS_INTEGRATED_BUTTON,		0, sizeof(struct bt_data),		0x83, DATAFORMAT(TYPE4),		{ SN_PRESSURE, 0, 300 },		{ SN_WIDTH, 0, 2048 },		{ SN_COORD, -4828, 5345 },		{ SN_COORD, -203, 6803 },		{ SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }	},	{}}; /* return the device-specific configuration by device */static const struct bcm5974_config *bcm5974_get_config(struct usb_device *udev){	u16 id = le16_to_cpu(udev->descriptor.idProduct);	const struct bcm5974_config *cfg; 	for (cfg = bcm5974_config_table; cfg->ansi; ++cfg)		if (cfg->ansi == id || cfg->iso == id || cfg->jis == id)			return cfg; 

Lines 1–500 of 1064.