PageRenderTime 110ms CodeModel.GetById 26ms app.highlight 77ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/input/mouse/bcm5974.c

https://bitbucket.org/abioy/linux
C | 822 lines | 582 code | 131 blank | 109 comment | 58 complexity | 00f56f9102cfa1e306a4ae23a9375be4 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, GPL-2.0, LGPL-2.0, AGPL-1.0
  1/*
  2 * Apple USB BCM5974 (Macbook Air and Penryn Macbook Pro) multitouch driver
  3 *
  4 * Copyright (C) 2008	   Henrik Rydberg (rydberg@euromail.se)
  5 *
  6 * The USB initialization and package decoding was made by
  7 * Scott Shawcroft as part of the touchd user-space driver project:
  8 * Copyright (C) 2008	   Scott Shawcroft (scott.shawcroft@gmail.com)
  9 *
 10 * The BCM5974 driver is based on the appletouch driver:
 11 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
 12 * Copyright (C) 2005      Johannes Berg (johannes@sipsolutions.net)
 13 * Copyright (C) 2005	   Stelian Pop (stelian@popies.net)
 14 * Copyright (C) 2005	   Frank Arnold (frank@scirocco-5v-turbo.de)
 15 * Copyright (C) 2005	   Peter Osterlund (petero2@telia.com)
 16 * Copyright (C) 2005	   Michael Hanselmann (linux-kernel@hansmi.ch)
 17 * Copyright (C) 2006	   Nicolas Boichat (nicolas@boichat.ch)
 18 *
 19 * This program is free software; you can redistribute it and/or modify
 20 * it under the terms of the GNU General Public License as published by
 21 * the Free Software Foundation; either version 2 of the License, or
 22 * (at your option) any later version.
 23 *
 24 * This program is distributed in the hope that it will be useful,
 25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 27 * GNU General Public License for more details.
 28 *
 29 * You should have received a copy of the GNU General Public License
 30 * along with this program; if not, write to the Free Software
 31 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 32 *
 33 */
 34
 35#include <linux/kernel.h>
 36#include <linux/errno.h>
 37#include <linux/init.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
 44#define USB_VENDOR_ID_APPLE		0x05ac
 45
 46/* MacbookAir, aka wellspring */
 47#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI	0x0223
 48#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO	0x0224
 49#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS	0x0225
 50/* MacbookProPenryn, aka wellspring2 */
 51#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI	0x0230
 52#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO	0x0231
 53#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS	0x0232
 54/* Macbook5,1 (unibody), aka wellspring3 */
 55#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI	0x0236
 56#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO	0x0237
 57#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS	0x0238
 58
 59#define BCM5974_DEVICE(prod) {					\
 60	.match_flags = (USB_DEVICE_ID_MATCH_DEVICE |		\
 61			USB_DEVICE_ID_MATCH_INT_CLASS |		\
 62			USB_DEVICE_ID_MATCH_INT_PROTOCOL),	\
 63	.idVendor = USB_VENDOR_ID_APPLE,			\
 64	.idProduct = (prod),					\
 65	.bInterfaceClass = USB_INTERFACE_CLASS_HID,		\
 66	.bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE	\
 67}
 68
 69/* table of devices that work with this driver */
 70static const struct usb_device_id bcm5974_table[] = {
 71	/* MacbookAir1.1 */
 72	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
 73	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
 74	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_JIS),
 75	/* MacbookProPenryn */
 76	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
 77	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
 78	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
 79	/* Macbook5,1 */
 80	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI),
 81	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO),
 82	BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS),
 83	/* Terminating entry */
 84	{}
 85};
 86MODULE_DEVICE_TABLE(usb, bcm5974_table);
 87
 88MODULE_AUTHOR("Henrik Rydberg");
 89MODULE_DESCRIPTION("Apple USB BCM5974 multitouch driver");
 90MODULE_LICENSE("GPL");
 91
 92#define dprintk(level, format, a...)\
 93	{ if (debug >= level) printk(KERN_DEBUG format, ##a); }
 94
 95static int debug = 1;
 96module_param(debug, int, 0644);
 97MODULE_PARM_DESC(debug, "Activate debugging output");
 98
 99/* button data structure */
100struct bt_data {
101	u8 unknown1;		/* constant */
102	u8 button;		/* left button */
103	u8 rel_x;		/* relative x coordinate */
104	u8 rel_y;		/* relative y coordinate */
105};
106
107/* trackpad header types */
108enum tp_type {
109	TYPE1,			/* plain trackpad */
110	TYPE2			/* button integrated in trackpad */
111};
112
113/* trackpad finger data offsets, le16-aligned */
114#define FINGER_TYPE1		(13 * sizeof(__le16))
115#define FINGER_TYPE2		(15 * sizeof(__le16))
116
117/* trackpad button data offsets */
118#define BUTTON_TYPE2		15
119
120/* list of device capability bits */
121#define HAS_INTEGRATED_BUTTON	1
122
123/* trackpad finger structure, le16-aligned */
124struct tp_finger {
125	__le16 origin;		/* zero when switching track finger */
126	__le16 abs_x;		/* absolute x coodinate */
127	__le16 abs_y;		/* absolute y coodinate */
128	__le16 rel_x;		/* relative x coodinate */
129	__le16 rel_y;		/* relative y coodinate */
130	__le16 size_major;	/* finger size, major axis? */
131	__le16 size_minor;	/* finger size, minor axis? */
132	__le16 orientation;	/* 16384 when point, else 15 bit angle */
133	__le16 force_major;	/* trackpad force, major axis? */
134	__le16 force_minor;	/* trackpad force, minor axis? */
135	__le16 unused[3];	/* zeros */
136	__le16 multi;		/* one finger: varies, more fingers: constant */
137} __attribute__((packed,aligned(2)));
138
139/* trackpad finger data size, empirically at least ten fingers */
140#define SIZEOF_FINGER		sizeof(struct tp_finger)
141#define SIZEOF_ALL_FINGERS	(16 * SIZEOF_FINGER)
142#define MAX_FINGER_ORIENTATION	16384
143
144/* device-specific parameters */
145struct bcm5974_param {
146	int dim;		/* logical dimension */
147	int fuzz;		/* logical noise value */
148	int devmin;		/* device minimum reading */
149	int devmax;		/* device maximum reading */
150};
151
152/* device-specific configuration */
153struct bcm5974_config {
154	int ansi, iso, jis;	/* the product id of this device */
155	int caps;		/* device capability bitmask */
156	int bt_ep;		/* the endpoint of the button interface */
157	int bt_datalen;		/* data length of the button interface */
158	int tp_ep;		/* the endpoint of the trackpad interface */
159	enum tp_type tp_type;	/* type of trackpad interface */
160	int tp_offset;		/* offset to trackpad finger data */
161	int tp_datalen;		/* data length of the trackpad interface */
162	struct bcm5974_param p;	/* finger pressure limits */
163	struct bcm5974_param w;	/* finger width limits */
164	struct bcm5974_param x;	/* horizontal limits */
165	struct bcm5974_param y;	/* vertical limits */
166};
167
168/* logical device structure */
169struct bcm5974 {
170	char phys[64];
171	struct usb_device *udev;	/* usb device */
172	struct usb_interface *intf;	/* our interface */
173	struct input_dev *input;	/* input dev */
174	struct bcm5974_config cfg;	/* device configuration */
175	struct mutex pm_mutex;		/* serialize access to open/suspend */
176	int opened;			/* 1: opened, 0: closed */
177	struct urb *bt_urb;		/* button usb request block */
178	struct bt_data *bt_data;	/* button transferred data */
179	struct urb *tp_urb;		/* trackpad usb request block */
180	u8 *tp_data;			/* trackpad transferred data */
181	int fingers;			/* number of fingers on trackpad */
182};
183
184/* logical dimensions */
185#define DIM_PRESSURE	256		/* maximum finger pressure */
186#define DIM_WIDTH	16		/* maximum finger width */
187#define DIM_X		1280		/* maximum trackpad x value */
188#define DIM_Y		800		/* maximum trackpad y value */
189
190/* logical signal quality */
191#define SN_PRESSURE	45		/* pressure signal-to-noise ratio */
192#define SN_WIDTH	100		/* width signal-to-noise ratio */
193#define SN_COORD	250		/* coordinate signal-to-noise ratio */
194
195/* pressure thresholds */
196#define PRESSURE_LOW	(2 * DIM_PRESSURE / SN_PRESSURE)
197#define PRESSURE_HIGH	(3 * PRESSURE_LOW)
198
199/* device constants */
200static const struct bcm5974_config bcm5974_config_table[] = {
201	{
202		USB_DEVICE_ID_APPLE_WELLSPRING_ANSI,
203		USB_DEVICE_ID_APPLE_WELLSPRING_ISO,
204		USB_DEVICE_ID_APPLE_WELLSPRING_JIS,
205		0,
206		0x84, sizeof(struct bt_data),
207		0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS,
208		{ DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
209		{ DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
210		{ DIM_X, DIM_X / SN_COORD, -4824, 5342 },
211		{ DIM_Y, DIM_Y / SN_COORD, -172, 5820 }
212	},
213	{
214		USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI,
215		USB_DEVICE_ID_APPLE_WELLSPRING2_ISO,
216		USB_DEVICE_ID_APPLE_WELLSPRING2_JIS,
217		0,
218		0x84, sizeof(struct bt_data),
219		0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS,
220		{ DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
221		{ DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
222		{ DIM_X, DIM_X / SN_COORD, -4824, 4824 },
223		{ DIM_Y, DIM_Y / SN_COORD, -172, 4290 }
224	},
225	{
226		USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI,
227		USB_DEVICE_ID_APPLE_WELLSPRING3_ISO,
228		USB_DEVICE_ID_APPLE_WELLSPRING3_JIS,
229		HAS_INTEGRATED_BUTTON,
230		0x84, sizeof(struct bt_data),
231		0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
232		{ DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 },
233		{ DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
234		{ DIM_X, DIM_X / SN_COORD, -4460, 5166 },
235		{ DIM_Y, DIM_Y / SN_COORD, -75, 6700 }
236	},
237	{}
238};
239
240/* return the device-specific configuration by device */
241static const struct bcm5974_config *bcm5974_get_config(struct usb_device *udev)
242{
243	u16 id = le16_to_cpu(udev->descriptor.idProduct);
244	const struct bcm5974_config *cfg;
245
246	for (cfg = bcm5974_config_table; cfg->ansi; ++cfg)
247		if (cfg->ansi == id || cfg->iso == id || cfg->jis == id)
248			return cfg;
249
250	return bcm5974_config_table;
251}
252
253/* convert 16-bit little endian to signed integer */
254static inline int raw2int(__le16 x)
255{
256	return (signed short)le16_to_cpu(x);
257}
258
259/* scale device data to logical dimensions (asserts devmin < devmax) */
260static inline int int2scale(const struct bcm5974_param *p, int x)
261{
262	return x * p->dim / (p->devmax - p->devmin);
263}
264
265/* all logical value ranges are [0,dim). */
266static inline int int2bound(const struct bcm5974_param *p, int x)
267{
268	int s = int2scale(p, x);
269
270	return clamp_val(s, 0, p->dim - 1);
271}
272
273/* setup which logical events to report */
274static void setup_events_to_report(struct input_dev *input_dev,
275				   const struct bcm5974_config *cfg)
276{
277	__set_bit(EV_ABS, input_dev->evbit);
278
279	input_set_abs_params(input_dev, ABS_PRESSURE,
280				0, cfg->p.dim, cfg->p.fuzz, 0);
281	input_set_abs_params(input_dev, ABS_TOOL_WIDTH,
282				0, cfg->w.dim, cfg->w.fuzz, 0);
283	input_set_abs_params(input_dev, ABS_X,
284				0, cfg->x.dim, cfg->x.fuzz, 0);
285	input_set_abs_params(input_dev, ABS_Y,
286				0, cfg->y.dim, cfg->y.fuzz, 0);
287
288	/* finger touch area */
289	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
290			     cfg->w.devmin, cfg->w.devmax, 0, 0);
291	input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR,
292			     cfg->w.devmin, cfg->w.devmax, 0, 0);
293	/* finger approach area */
294	input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR,
295			     cfg->w.devmin, cfg->w.devmax, 0, 0);
296	input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR,
297			     cfg->w.devmin, cfg->w.devmax, 0, 0);
298	/* finger orientation */
299	input_set_abs_params(input_dev, ABS_MT_ORIENTATION,
300			     -MAX_FINGER_ORIENTATION,
301			     MAX_FINGER_ORIENTATION, 0, 0);
302	/* finger position */
303	input_set_abs_params(input_dev, ABS_MT_POSITION_X,
304			     cfg->x.devmin, cfg->x.devmax, 0, 0);
305	input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
306			     cfg->y.devmin, cfg->y.devmax, 0, 0);
307
308	__set_bit(EV_KEY, input_dev->evbit);
309	__set_bit(BTN_TOUCH, input_dev->keybit);
310	__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
311	__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
312	__set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
313	__set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
314	__set_bit(BTN_LEFT, input_dev->keybit);
315}
316
317/* report button data as logical button state */
318static int report_bt_state(struct bcm5974 *dev, int size)
319{
320	if (size != sizeof(struct bt_data))
321		return -EIO;
322
323	dprintk(7,
324		"bcm5974: button data: %x %x %x %x\n",
325		dev->bt_data->unknown1, dev->bt_data->button,
326		dev->bt_data->rel_x, dev->bt_data->rel_y);
327
328	input_report_key(dev->input, BTN_LEFT, dev->bt_data->button);
329	input_sync(dev->input);
330
331	return 0;
332}
333
334static void report_finger_data(struct input_dev *input,
335			       const struct bcm5974_config *cfg,
336			       const struct tp_finger *f)
337{
338	input_report_abs(input, ABS_MT_TOUCH_MAJOR, raw2int(f->force_major));
339	input_report_abs(input, ABS_MT_TOUCH_MINOR, raw2int(f->force_minor));
340	input_report_abs(input, ABS_MT_WIDTH_MAJOR, raw2int(f->size_major));
341	input_report_abs(input, ABS_MT_WIDTH_MINOR, raw2int(f->size_minor));
342	input_report_abs(input, ABS_MT_ORIENTATION,
343			 MAX_FINGER_ORIENTATION - raw2int(f->orientation));
344	input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x));
345	input_report_abs(input, ABS_MT_POSITION_Y,
346			 cfg->y.devmin + cfg->y.devmax - raw2int(f->abs_y));
347	input_mt_sync(input);
348}
349
350/* report trackpad data as logical trackpad state */
351static int report_tp_state(struct bcm5974 *dev, int size)
352{
353	const struct bcm5974_config *c = &dev->cfg;
354	const struct tp_finger *f;
355	struct input_dev *input = dev->input;
356	int raw_p, raw_w, raw_x, raw_y, raw_n, i;
357	int ptest, origin, ibt = 0, nmin = 0, nmax = 0;
358	int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
359
360	if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0)
361		return -EIO;
362
363	/* finger data, le16-aligned */
364	f = (const struct tp_finger *)(dev->tp_data + c->tp_offset);
365	raw_n = (size - c->tp_offset) / SIZEOF_FINGER;
366
367	/* always track the first finger; when detached, start over */
368	if (raw_n) {
369
370		/* report raw trackpad data */
371		for (i = 0; i < raw_n; i++)
372			report_finger_data(input, c, &f[i]);
373
374		raw_p = raw2int(f->force_major);
375		raw_w = raw2int(f->size_major);
376		raw_x = raw2int(f->abs_x);
377		raw_y = raw2int(f->abs_y);
378
379		dprintk(9,
380			"bcm5974: "
381			"raw: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n",
382			raw_p, raw_w, raw_x, raw_y, raw_n);
383
384		ptest = int2bound(&c->p, raw_p);
385		origin = raw2int(f->origin);
386
387		/* set the integrated button if applicable */
388		if (c->tp_type == TYPE2)
389			ibt = raw2int(dev->tp_data[BUTTON_TYPE2]);
390
391		/* while tracking finger still valid, count all fingers */
392		if (ptest > PRESSURE_LOW && origin) {
393			abs_p = ptest;
394			abs_w = int2bound(&c->w, raw_w);
395			abs_x = int2bound(&c->x, raw_x - c->x.devmin);
396			abs_y = int2bound(&c->y, c->y.devmax - raw_y);
397			while (raw_n--) {
398				ptest = int2bound(&c->p,
399						  raw2int(f->force_major));
400				if (ptest > PRESSURE_LOW)
401					nmax++;
402				if (ptest > PRESSURE_HIGH)
403					nmin++;
404				f++;
405			}
406		}
407	}
408
409	if (dev->fingers < nmin)
410		dev->fingers = nmin;
411	if (dev->fingers > nmax)
412		dev->fingers = nmax;
413
414	input_report_key(input, BTN_TOUCH, dev->fingers > 0);
415	input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1);
416	input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2);
417	input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers == 3);
418	input_report_key(input, BTN_TOOL_QUADTAP, dev->fingers > 3);
419
420	input_report_abs(input, ABS_PRESSURE, abs_p);
421	input_report_abs(input, ABS_TOOL_WIDTH, abs_w);
422
423	if (abs_p) {
424		input_report_abs(input, ABS_X, abs_x);
425		input_report_abs(input, ABS_Y, abs_y);
426
427		dprintk(8,
428			"bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d "
429			"nmin: %d nmax: %d n: %d ibt: %d\n", abs_p, abs_w,
430			abs_x, abs_y, nmin, nmax, dev->fingers, ibt);
431
432	}
433
434	/* type 2 reports button events via ibt only */
435	if (c->tp_type == TYPE2)
436		input_report_key(input, BTN_LEFT, ibt);
437
438	input_sync(input);
439
440	return 0;
441}
442
443/* Wellspring initialization constants */
444#define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID		1
445#define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID	9
446#define BCM5974_WELLSPRING_MODE_REQUEST_VALUE		0x300
447#define BCM5974_WELLSPRING_MODE_REQUEST_INDEX		0
448#define BCM5974_WELLSPRING_MODE_VENDOR_VALUE		0x01
449#define BCM5974_WELLSPRING_MODE_NORMAL_VALUE		0x08
450
451static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on)
452{
453	char *data = kmalloc(8, GFP_KERNEL);
454	int retval = 0, size;
455
456	if (!data) {
457		err("bcm5974: out of memory");
458		retval = -ENOMEM;
459		goto out;
460	}
461
462	/* read configuration */
463	size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
464			BCM5974_WELLSPRING_MODE_READ_REQUEST_ID,
465			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
466			BCM5974_WELLSPRING_MODE_REQUEST_VALUE,
467			BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000);
468
469	if (size != 8) {
470		err("bcm5974: could not read from device");
471		retval = -EIO;
472		goto out;
473	}
474
475	/* apply the mode switch */
476	data[0] = on ?
477		BCM5974_WELLSPRING_MODE_VENDOR_VALUE :
478		BCM5974_WELLSPRING_MODE_NORMAL_VALUE;
479
480	/* write configuration */
481	size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
482			BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID,
483			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
484			BCM5974_WELLSPRING_MODE_REQUEST_VALUE,
485			BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000);
486
487	if (size != 8) {
488		err("bcm5974: could not write to device");
489		retval = -EIO;
490		goto out;
491	}
492
493	dprintk(2, "bcm5974: switched to %s mode.\n",
494		on ? "wellspring" : "normal");
495
496 out:
497	kfree(data);
498	return retval;
499}
500
501static void bcm5974_irq_button(struct urb *urb)
502{
503	struct bcm5974 *dev = urb->context;
504	int error;
505
506	switch (urb->status) {
507	case 0:
508		break;
509	case -EOVERFLOW:
510	case -ECONNRESET:
511	case -ENOENT:
512	case -ESHUTDOWN:
513		dbg("bcm5974: button urb shutting down: %d", urb->status);
514		return;
515	default:
516		dbg("bcm5974: button urb status: %d", urb->status);
517		goto exit;
518	}
519
520	if (report_bt_state(dev, dev->bt_urb->actual_length))
521		dprintk(1, "bcm5974: bad button package, length: %d\n",
522			dev->bt_urb->actual_length);
523
524exit:
525	error = usb_submit_urb(dev->bt_urb, GFP_ATOMIC);
526	if (error)
527		err("bcm5974: button urb failed: %d", error);
528}
529
530static void bcm5974_irq_trackpad(struct urb *urb)
531{
532	struct bcm5974 *dev = urb->context;
533	int error;
534
535	switch (urb->status) {
536	case 0:
537		break;
538	case -EOVERFLOW:
539	case -ECONNRESET:
540	case -ENOENT:
541	case -ESHUTDOWN:
542		dbg("bcm5974: trackpad urb shutting down: %d", urb->status);
543		return;
544	default:
545		dbg("bcm5974: trackpad urb status: %d", urb->status);
546		goto exit;
547	}
548
549	/* control response ignored */
550	if (dev->tp_urb->actual_length == 2)
551		goto exit;
552
553	if (report_tp_state(dev, dev->tp_urb->actual_length))
554		dprintk(1, "bcm5974: bad trackpad package, length: %d\n",
555			dev->tp_urb->actual_length);
556
557exit:
558	error = usb_submit_urb(dev->tp_urb, GFP_ATOMIC);
559	if (error)
560		err("bcm5974: trackpad urb failed: %d", error);
561}
562
563/*
564 * The Wellspring trackpad, like many recent Apple trackpads, share
565 * the usb device with the keyboard. Since keyboards are usually
566 * handled by the HID system, the device ends up being handled by two
567 * modules. Setting up the device therefore becomes slightly
568 * complicated. To enable multitouch features, a mode switch is
569 * required, which is usually applied via the control interface of the
570 * device.  It can be argued where this switch should take place. In
571 * some drivers, like appletouch, the switch is made during
572 * probe. However, the hid module may also alter the state of the
573 * device, resulting in trackpad malfunction under certain
574 * circumstances. To get around this problem, there is at least one
575 * example that utilizes the USB_QUIRK_RESET_RESUME quirk in order to
576 * recieve a reset_resume request rather than the normal resume.
577 * Since the implementation of reset_resume is equal to mode switch
578 * plus start_traffic, it seems easier to always do the switch when
579 * starting traffic on the device.
580 */
581static int bcm5974_start_traffic(struct bcm5974 *dev)
582{
583	if (bcm5974_wellspring_mode(dev, true)) {
584		dprintk(1, "bcm5974: mode switch failed\n");
585		goto error;
586	}
587
588	if (usb_submit_urb(dev->bt_urb, GFP_KERNEL))
589		goto error;
590
591	if (usb_submit_urb(dev->tp_urb, GFP_KERNEL))
592		goto err_kill_bt;
593
594	return 0;
595
596err_kill_bt:
597	usb_kill_urb(dev->bt_urb);
598error:
599	return -EIO;
600}
601
602static void bcm5974_pause_traffic(struct bcm5974 *dev)
603{
604	usb_kill_urb(dev->tp_urb);
605	usb_kill_urb(dev->bt_urb);
606	bcm5974_wellspring_mode(dev, false);
607}
608
609/*
610 * The code below implements open/close and manual suspend/resume.
611 * All functions may be called in random order.
612 *
613 * Opening a suspended device fails with EACCES - permission denied.
614 *
615 * Failing a resume leaves the device resumed but closed.
616 */
617static int bcm5974_open(struct input_dev *input)
618{
619	struct bcm5974 *dev = input_get_drvdata(input);
620	int error;
621
622	error = usb_autopm_get_interface(dev->intf);
623	if (error)
624		return error;
625
626	mutex_lock(&dev->pm_mutex);
627
628	error = bcm5974_start_traffic(dev);
629	if (!error)
630		dev->opened = 1;
631
632	mutex_unlock(&dev->pm_mutex);
633
634	if (error)
635		usb_autopm_put_interface(dev->intf);
636
637	return error;
638}
639
640static void bcm5974_close(struct input_dev *input)
641{
642	struct bcm5974 *dev = input_get_drvdata(input);
643
644	mutex_lock(&dev->pm_mutex);
645
646	bcm5974_pause_traffic(dev);
647	dev->opened = 0;
648
649	mutex_unlock(&dev->pm_mutex);
650
651	usb_autopm_put_interface(dev->intf);
652}
653
654static int bcm5974_suspend(struct usb_interface *iface, pm_message_t message)
655{
656	struct bcm5974 *dev = usb_get_intfdata(iface);
657
658	mutex_lock(&dev->pm_mutex);
659
660	if (dev->opened)
661		bcm5974_pause_traffic(dev);
662
663	mutex_unlock(&dev->pm_mutex);
664
665	return 0;
666}
667
668static int bcm5974_resume(struct usb_interface *iface)
669{
670	struct bcm5974 *dev = usb_get_intfdata(iface);
671	int error = 0;
672
673	mutex_lock(&dev->pm_mutex);
674
675	if (dev->opened)
676		error = bcm5974_start_traffic(dev);
677
678	mutex_unlock(&dev->pm_mutex);
679
680	return error;
681}
682
683static int bcm5974_probe(struct usb_interface *iface,
684			 const struct usb_device_id *id)
685{
686	struct usb_device *udev = interface_to_usbdev(iface);
687	const struct bcm5974_config *cfg;
688	struct bcm5974 *dev;
689	struct input_dev *input_dev;
690	int error = -ENOMEM;
691
692	/* find the product index */
693	cfg = bcm5974_get_config(udev);
694
695	/* allocate memory for our device state and initialize it */
696	dev = kzalloc(sizeof(struct bcm5974), GFP_KERNEL);
697	input_dev = input_allocate_device();
698	if (!dev || !input_dev) {
699		err("bcm5974: out of memory");
700		goto err_free_devs;
701	}
702
703	dev->udev = udev;
704	dev->intf = iface;
705	dev->input = input_dev;
706	dev->cfg = *cfg;
707	mutex_init(&dev->pm_mutex);
708
709	/* setup urbs */
710	dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL);
711	if (!dev->bt_urb)
712		goto err_free_devs;
713
714	dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL);
715	if (!dev->tp_urb)
716		goto err_free_bt_urb;
717
718	dev->bt_data = usb_buffer_alloc(dev->udev,
719					dev->cfg.bt_datalen, GFP_KERNEL,
720					&dev->bt_urb->transfer_dma);
721	if (!dev->bt_data)
722		goto err_free_urb;
723
724	dev->tp_data = usb_buffer_alloc(dev->udev,
725					dev->cfg.tp_datalen, GFP_KERNEL,
726					&dev->tp_urb->transfer_dma);
727	if (!dev->tp_data)
728		goto err_free_bt_buffer;
729
730	usb_fill_int_urb(dev->bt_urb, udev,
731			 usb_rcvintpipe(udev, cfg->bt_ep),
732			 dev->bt_data, dev->cfg.bt_datalen,
733			 bcm5974_irq_button, dev, 1);
734
735	usb_fill_int_urb(dev->tp_urb, udev,
736			 usb_rcvintpipe(udev, cfg->tp_ep),
737			 dev->tp_data, dev->cfg.tp_datalen,
738			 bcm5974_irq_trackpad, dev, 1);
739
740	/* create bcm5974 device */
741	usb_make_path(udev, dev->phys, sizeof(dev->phys));
742	strlcat(dev->phys, "/input0", sizeof(dev->phys));
743
744	input_dev->name = "bcm5974";
745	input_dev->phys = dev->phys;
746	usb_to_input_id(dev->udev, &input_dev->id);
747	/* report driver capabilities via the version field */
748	input_dev->id.version = cfg->caps;
749	input_dev->dev.parent = &iface->dev;
750
751	input_set_drvdata(input_dev, dev);
752
753	input_dev->open = bcm5974_open;
754	input_dev->close = bcm5974_close;
755
756	setup_events_to_report(input_dev, cfg);
757
758	error = input_register_device(dev->input);
759	if (error)
760		goto err_free_buffer;
761
762	/* save our data pointer in this interface device */
763	usb_set_intfdata(iface, dev);
764
765	return 0;
766
767err_free_buffer:
768	usb_buffer_free(dev->udev, dev->cfg.tp_datalen,
769		dev->tp_data, dev->tp_urb->transfer_dma);
770err_free_bt_buffer:
771	usb_buffer_free(dev->udev, dev->cfg.bt_datalen,
772		dev->bt_data, dev->bt_urb->transfer_dma);
773err_free_urb:
774	usb_free_urb(dev->tp_urb);
775err_free_bt_urb:
776	usb_free_urb(dev->bt_urb);
777err_free_devs:
778	usb_set_intfdata(iface, NULL);
779	input_free_device(input_dev);
780	kfree(dev);
781	return error;
782}
783
784static void bcm5974_disconnect(struct usb_interface *iface)
785{
786	struct bcm5974 *dev = usb_get_intfdata(iface);
787
788	usb_set_intfdata(iface, NULL);
789
790	input_unregister_device(dev->input);
791	usb_buffer_free(dev->udev, dev->cfg.tp_datalen,
792			dev->tp_data, dev->tp_urb->transfer_dma);
793	usb_buffer_free(dev->udev, dev->cfg.bt_datalen,
794			dev->bt_data, dev->bt_urb->transfer_dma);
795	usb_free_urb(dev->tp_urb);
796	usb_free_urb(dev->bt_urb);
797	kfree(dev);
798}
799
800static struct usb_driver bcm5974_driver = {
801	.name			= "bcm5974",
802	.probe			= bcm5974_probe,
803	.disconnect		= bcm5974_disconnect,
804	.suspend		= bcm5974_suspend,
805	.resume			= bcm5974_resume,
806	.id_table		= bcm5974_table,
807	.supports_autosuspend	= 1,
808};
809
810static int __init bcm5974_init(void)
811{
812	return usb_register(&bcm5974_driver);
813}
814
815static void __exit bcm5974_exit(void)
816{
817	usb_deregister(&bcm5974_driver);
818}
819
820module_init(bcm5974_init);
821module_exit(bcm5974_exit);
822