summaryrefslogtreecommitdiff
path: root/bcm5974.c
diff options
context:
space:
mode:
Diffstat (limited to 'bcm5974.c')
-rw-r--r--bcm5974.c1079
1 files changed, 540 insertions, 539 deletions
diff --git a/bcm5974.c b/bcm5974.c
index 68f92c5..a7f070f 100644
--- a/bcm5974.c
+++ b/bcm5974.c
@@ -9,7 +9,7 @@
9 * 9 *
10 * The BCM5974 driver is based on the appletouch driver: 10 * The BCM5974 driver is based on the appletouch driver:
11 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) 11 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
12 * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net) 12 * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net)
13 * Copyright (C) 2005 Stelian Pop (stelian@popies.net) 13 * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
14 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) 14 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
15 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) 15 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
@@ -40,650 +40,651 @@
40#include <linux/usb/input.h> 40#include <linux/usb/input.h>
41#include <linux/hid.h> 41#include <linux/hid.h>
42 42
43#define APPLE_VENDOR_ID 0x05AC 43#define APPLE_VENDOR_ID 0x05AC
44 44
45/* MacbookAir BCM5974, aka wellspring */ 45/* MacbookAir, aka wellspring */
46 46#define ATP_WELLSPRING_ANSI 0x0223
47#define ATP_WELLSPRING_ANSI 0x0223 47#define ATP_WELLSPRING_ISO 0x0224
48#define ATP_WELLSPRING_ISO 0x0224 48#define ATP_WELLSPRING_JIS 0x0225
49#define ATP_WELLSPRING_JIS 0x0225 49/* MacbookProPenryn, aka wellspring2 */
50#define ATP_WELLSPRING2_ANSI 0x0230 50#define ATP_WELLSPRING2_ANSI 0x0230
51#define ATP_WELLSPRING2_ISO 0x0231 51#define ATP_WELLSPRING2_ISO 0x0231
52#define ATP_WELLSPRING2_JIS 0x0232 52#define ATP_WELLSPRING2_JIS 0x0232
53 53
54#define ATP_DEVICE(prod) { \ 54#define ATP_DEVICE(prod) { \
55 .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ 55 .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \
56 USB_DEVICE_ID_MATCH_INT_CLASS | \ 56 USB_DEVICE_ID_MATCH_INT_CLASS | \
57 USB_DEVICE_ID_MATCH_INT_PROTOCOL), \ 57 USB_DEVICE_ID_MATCH_INT_PROTOCOL), \
58 .idVendor = APPLE_VENDOR_ID, \ 58 .idVendor = APPLE_VENDOR_ID, \
59 .idProduct = (prod), \ 59 .idProduct = (prod), \
60 .bInterfaceClass = USB_INTERFACE_CLASS_HID, \ 60 .bInterfaceClass = USB_INTERFACE_CLASS_HID, \
61 .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE \ 61 .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE \
62 } 62}
63 63
64/* table of devices that work with this driver */ 64/* table of devices that work with this driver */
65static const struct usb_device_id atp_table [] = { 65static const struct usb_device_id atp_table [] = {
66 /* MacbookAir1.1 */ 66 /* MacbookAir1.1 */
67 ATP_DEVICE(ATP_WELLSPRING_ANSI), 67 ATP_DEVICE(ATP_WELLSPRING_ANSI),
68 ATP_DEVICE(ATP_WELLSPRING_ISO), 68 ATP_DEVICE(ATP_WELLSPRING_ISO),
69 ATP_DEVICE(ATP_WELLSPRING_JIS), 69 ATP_DEVICE(ATP_WELLSPRING_JIS),
70 70 /* MacbookProPenryn */
71 /* MacbookProPenryn */ 71 ATP_DEVICE(ATP_WELLSPRING2_ANSI),
72 ATP_DEVICE(ATP_WELLSPRING2_ANSI), 72 ATP_DEVICE(ATP_WELLSPRING2_ISO),
73 ATP_DEVICE(ATP_WELLSPRING2_ISO), 73 ATP_DEVICE(ATP_WELLSPRING2_JIS),
74 ATP_DEVICE(ATP_WELLSPRING2_JIS), 74 /* Terminating entry */
75 75 {}
76 /* Terminating entry */
77 {}
78}; 76};
79MODULE_DEVICE_TABLE(usb, atp_table); 77MODULE_DEVICE_TABLE(usb, atp_table);
80 78
81struct atp_params_t { 79MODULE_AUTHOR("Henrik Rydberg");
82 int devmin; /* device minimum reading */ 80MODULE_DESCRIPTION("Apple USB BCM5974 multitouch driver");
83 int devmax; /* device maximum reading */ 81MODULE_LICENSE("GPL");
84 int min; /* logical minimum reading */
85 int max; /* logical maximum reading */
86 int fuzz; /* reading noise value */
87 int flat; /* zero */
88};
89 82
90struct atp_config_t { 83#define dprintk(level, format, a...)\
91 int ansi, iso, jis; /* the product id of this device */ 84 { if (debug >= level) printk(KERN_DEBUG format, ##a); }
92 int bt_ep; /* the endpoint of the button interface */ 85
93 int bt_datalen; /* data length of the button interface */ 86static int debug = 1;
94 int tp_ep; /* the endpoint of the trackpad interface */ 87module_param(debug, int, 0644);
95 int tp_datalen; /* data length of the trackpad interface */ 88MODULE_PARM_DESC(debug, "Activate debugging output");
96 struct atp_params_t x; /* horizontal limits */ 89
97 struct atp_params_t y; /* vertical limits */ 90/* button data structure */
98 struct atp_params_t p; /* finger pressure limits */ 91struct bt_data {
99 struct atp_params_t w; /* finger width limits */ 92 u8 unknown1; /* constant */
93 u8 button; /* left button */
94 u8 rel_x; /* relative x coordinate */
95 u8 rel_y; /* relative y coordinate */
100}; 96};
101 97
102/* trackpad header structure */ 98/* trackpad header structure */
103struct tp_header_t { 99struct tp_header {
104 u8 unknown1[16]; /* constants, timers, etc */ 100 u8 unknown1[16]; /* constants, timers, etc */
105 u8 nfinger; /* number of fingers on trackpad */ 101 u8 fingers; /* number of fingers on trackpad */
106 u8 unknown2[9]; /* constants, timers, etc */ 102 u8 unknown2[9]; /* constants, timers, etc */
107}; 103};
108 104
109/* trackpad finger structure */ 105/* trackpad finger structure */
110struct tp_finger_t { 106struct tp_finger {
111 __le16 origin; /* left/right origin? */ 107 __le16 origin; /* left/right origin? */
112 __le16 abs_x; /* absolute x coodinate */ 108 __le16 abs_x; /* absolute x coodinate */
113 __le16 abs_y; /* absolute y coodinate */ 109 __le16 abs_y; /* absolute y coodinate */
114 __le16 rel_x; /* relative x coodinate */ 110 __le16 rel_x; /* relative x coodinate */
115 __le16 rel_y; /* relative y coodinate */ 111 __le16 rel_y; /* relative y coodinate */
116 __le16 size_major; /* finger size, major axis? */ 112 __le16 size_major; /* finger size, major axis? */
117 __le16 size_minor; /* finger size, minor axis? */ 113 __le16 size_minor; /* finger size, minor axis? */
118 __le16 orientation; /* 16384 when point, else 15 bit angle */ 114 __le16 orientation; /* 16384 when point, else 15 bit angle */
119 __le16 force_major; /* trackpad force, major axis? */ 115 __le16 force_major; /* trackpad force, major axis? */
120 __le16 force_minor; /* trackpad force, minor axis? */ 116 __le16 force_minor; /* trackpad force, minor axis? */
121 __le16 unused[3]; /* zeros */ 117 __le16 unused[3]; /* zeros */
122 __le16 multi; /* one finger: varies, more fingers: constant */ 118 __le16 multi; /* one finger: varies, more fingers: constant */
123}; 119};
124 120
125/* trackpad data structure */ 121/* trackpad data structure, empirically at least ten fingers */
126struct tp_data_t { 122struct tp_data {
127 struct tp_header_t header; 123 struct tp_header header;
128 struct tp_finger_t finger[16]; 124 struct tp_finger finger[16];
129}; 125};
130 126
131/* device constants */ 127/* device-specific parameters */
132static const struct atp_config_t atp_config_table[] = { 128struct atp_params {
133 { 129 int dim; /* logical dimension */
134 ATP_WELLSPRING_ANSI, 130 int devmin; /* device minimum reading */
135 ATP_WELLSPRING_ISO, 131 int devmax; /* device maximum reading */
136 ATP_WELLSPRING_JIS,
137 0x84, 4,
138 0x81, sizeof(struct tp_data_t),
139 {-4824, 5342, 0, 1280, 16, 0},
140 {-172, 5820, 0, 800, 16, 0},
141 {0, 256, 0, 256, 16, 0},
142 {0, 2048, 0, 256, 16, 0}
143 },
144 {
145 ATP_WELLSPRING2_ANSI,
146 ATP_WELLSPRING2_ISO,
147 ATP_WELLSPRING2_JIS,
148 0x84, 4,
149 0x81, sizeof(struct tp_data_t),
150 {-4824, 5342, 0, 1280, 16, 0},
151 {-172, 5820, 0, 800, 16, 0},
152 {0, 256, 0, 256, 16, 0},
153 {0, 2048, 0, 256, 16, 0}
154 },
155 {}
156}; 132};
157 133
158static inline 134/* device-specific configuration */
159const struct atp_config_t *atp_product_config(struct usb_device *udev) 135struct atp_config {
160{ 136 int ansi, iso, jis; /* the product id of this device */
161 u16 id = le16_to_cpu(udev->descriptor.idProduct); 137 int bt_ep; /* the endpoint of the button interface */
162 const struct atp_config_t *config; 138 int bt_datalen; /* data length of the button interface */
163 for (config = atp_config_table; config->ansi; ++config) 139 int tp_ep; /* the endpoint of the trackpad interface */
164 if (config->ansi == id || config->iso == id || config->jis == id) 140 int tp_datalen; /* data length of the trackpad interface */
165 return config; 141 struct atp_params p; /* finger pressure limits */
166 return atp_config_table; 142 struct atp_params w; /* finger width limits */
167} 143 struct atp_params x; /* horizontal limits */
144 struct atp_params y; /* vertical limits */
145};
168 146
169/* Wellspring initialization constants */ 147/* logical trackpad state */
170#define ATP_WELLSPRING_MODE_READ_REQUEST_ID 1 148struct tp_state {
171#define ATP_WELLSPRING_MODE_WRITE_REQUEST_ID 9 149 int pressure; /* finger pressure value */
172#define ATP_WELLSPRING_MODE_REQUEST_VALUE 0x300 150 int width; /* finger width value */
173#define ATP_WELLSPRING_MODE_REQUEST_INDEX 0 151 int abs_x; /* absolute x coordinate */
174#define ATP_WELLSPRING_MODE_VENDOR_VALUE_1 0x01 152 int abs_y; /* absolute y coordinate */
175#define ATP_WELLSPRING_MODE_VENDOR_VALUE_2 0x05 153 int fingers; /* number of fingers on trackpad */
154};
176 155
177#define dprintk(format, a...) \ 156/* logical device structure */
178 { if (debug) printk(KERN_DEBUG format, ##a); } 157struct atp {
158 char phys[64];
159 struct usb_device *udev; /* usb device */
160 struct input_dev *input; /* input dev */
161 struct atp_config cfg; /* device configuration */
162 int open; /* >0: open, else closed */
163 int suspended; /* >0: suspended, else open */
164 struct urb *bt_urb; /* button usb request block */
165 struct bt_data *bt_data; /* button transferred data */
166 unsigned bt_prev_state; /* logical button previous state */
167 unsigned bt_state; /* logical button state */
168 struct urb *tp_urb; /* trackpad usb request block */
169 struct tp_data *tp_data; /* trackpad transferred data */
170 struct tp_state tp_state; /* logical trackpad state */
171 unsigned tp_valid; /* trackpad sensors valid */
172};
179 173
180MODULE_AUTHOR("Henrik Rydberg"); 174/* logical dimensions */
181MODULE_DESCRIPTION("Apple USB BCM5974 multitouch driver"); 175#define DIM_PRESSURE 256 /* maximum finger pressure */
182MODULE_LICENSE("GPL"); 176#define DIM_WIDTH 16 /* maximum finger width */
177#define DIM_X 1280 /* maximum trackpad x value */
178#define DIM_Y 800 /* maximum trackpad y value */
179#define SNRATIO 50 /* signal to noise ratio */
183 180
184static int debug = 1; 181/* device constants */
185module_param(debug, int, 0644); 182static const struct atp_config atp_config_table[] = {
186MODULE_PARM_DESC(debug, "Activate debugging output"); 183 {
184 ATP_WELLSPRING_ANSI,
185 ATP_WELLSPRING_ISO,
186 ATP_WELLSPRING_JIS,
187 0x84, sizeof(struct bt_data),
188 0x81, sizeof(struct tp_data),
189 { DIM_PRESSURE, 0, 256 },
190 { DIM_WIDTH, 0, 2048 },
191 { DIM_X, -4824, 5342 },
192 { DIM_Y, -172, 5820 }
193 },
194 {
195 ATP_WELLSPRING2_ANSI,
196 ATP_WELLSPRING2_ISO,
197 ATP_WELLSPRING2_JIS,
198 0x84, sizeof(struct bt_data),
199 0x81, sizeof(struct tp_data),
200 { DIM_PRESSURE, 0, 256 },
201 { DIM_WIDTH, 0, 2048 },
202 { DIM_X, -4824, 5342 },
203 { DIM_Y, -172, 5820 }
204 },
205 {}
206};
187 207
188static int atp_wellspring_init(struct usb_device *udev) 208/* return the device-specific configuration by device */
209static const struct atp_config *atp_product_config(struct usb_device *udev)
189{ 210{
190 const struct atp_config_t *cfg = atp_product_config(udev); 211 u16 id = le16_to_cpu(udev->descriptor.idProduct);
191 char *data = kmalloc(8, GFP_KERNEL); 212 const struct atp_config *config;
192 int size; 213 for (config = atp_config_table; config->ansi; ++config)
193 214 if (config->ansi == id || config->iso == id ||
194 /* reset button endpoint */ 215 config->jis == id)
195 if (usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 216 return config;
196 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 217 return atp_config_table;
197 0, cfg->bt_ep, NULL, 0, 5000)) {
198 err("Could not reset button endpoint");
199 goto error;
200 }
201
202 /* reset trackpad endpoint */
203 if (usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
204 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
205 0, cfg->tp_ep, NULL, 0, 5000)) {
206 err("Could not reset trackpad endpoint");
207 goto error;
208 }
209
210 /* read configuration */
211 size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
212 ATP_WELLSPRING_MODE_READ_REQUEST_ID,
213 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
214 ATP_WELLSPRING_MODE_REQUEST_VALUE,
215 ATP_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000);
216
217 if (size != 8) {
218 err("Could not do mode read request from device (Wellspring Raw mode)");
219 goto error;
220 }
221
222 /* apply the mode switch */
223 data[0] = ATP_WELLSPRING_MODE_VENDOR_VALUE_1;
224 data[1] = ATP_WELLSPRING_MODE_VENDOR_VALUE_2;
225
226 /* write configuration */
227 size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
228 ATP_WELLSPRING_MODE_WRITE_REQUEST_ID,
229 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
230 ATP_WELLSPRING_MODE_REQUEST_VALUE,
231 ATP_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000);
232
233 if (size != 8) {
234 err("Could not do mode write request to device (Wellspring Raw mode)");
235 goto error;
236 }
237
238 printk(KERN_INFO "bcm5974: Wellspring mode initialized.\n");
239
240 kfree(data);
241 return 0;
242
243 error:
244 kfree(data);
245 return -EIO;
246} 218}
247 219
248/* Structure to hold all of our device specific stuff */ 220/* convert 16-bit little endian to signed integer */
249struct atp {
250 char phys[64];
251 struct usb_device *udev; /* usb device */
252 struct input_dev *input; /* input dev */
253 struct atp_config_t cfg; /* device configuration */
254 int open; /* >0: open, else closed */
255 int suspended; /* >0: suspended, else open */
256 struct urb *bt_urb; /* button usb request block */
257 signed char *bt_data; /* button transferred data */
258 unsigned bt_state; /* current button state */
259 struct urb *tp_urb; /* trackpad usb request block */
260 signed char *tp_data; /* trackpad transferred data */
261 unsigned tp_valid; /* are the trackpad sensors valid ? */
262};
263
264static inline int raw2int(__le16 x) 221static inline int raw2int(__le16 x)
265{ 222{
266 return (short)le16_to_cpu(x); 223 return (signed short)le16_to_cpu(x);
267} 224}
268 225
269static inline int int2scale(const struct atp_params_t *p, int x) 226/* scale device data to logical dimensions (asserts devmin < devmax) */
227static inline int int2scale(const struct atp_params *p, int x)
270{ 228{
271 return ((p->max-p->min)*x)/(p->devmax-p->devmin); 229 return x * p->dim / (p->devmax - p->devmin);
272} 230}
273 231
274/** 232/* all logical value ranges are [0,dim). */
275 * all value ranges, both device and logical, are assumed to be [a,b). 233static inline int int2bound(const struct atp_params *p, int x)
276 */
277static inline int int2bound(const struct atp_params_t *p, int x)
278{ 234{
279 int s = p->min+int2scale(p, x); 235 int s = int2scale(p, x);
280 return s < p->min?p->min:s >= p->max?p->max-1:s; 236 return s < 0 ? 0 : s >= p->dim ? p->dim - 1 : s;
281} 237}
282 238
283/** 239/* convert button data to logical button state */
284 * check quality of reading. 240static int compute_bt_state(struct atp *dev, int size)
285 * -1: bad data
286 * 0: ignore this reading
287 * 1: good reading
288 */
289static int compute_quality(const unsigned char *data, int size)
290{ 241{
291 if (size < 26 || (size-26)%28 != 0) 242 if (size != sizeof(struct bt_data))
292 return -1; 243 return -EIO;
293 244
294 return 1; 245 dev->bt_prev_state = dev->bt_state;
246 dev->bt_state = dev->bt_data->button;
247
248 return 0;
295} 249}
296 250
297/** 251/* convert trackpad data to logical trackpad state */
298 * convert raw data to synaptics sensor output. 252static int compute_tp_state(struct atp *dev, int size)
299 * returns the number of fingers on the trackpad,
300 * or a negative number in vase of bad data.
301 */
302static int compute_movement(int *abs_x, int *abs_y,
303 int *rel_x, int *rel_y,
304 int *pressure, int *width,
305 struct atp_config_t *cfg,
306 const unsigned char *data, int size)
307{ 253{
308 const int nfinger = (size-26)/28; 254 const struct atp_config *c = &dev->cfg;
309 const struct tp_data_t *tp = (struct tp_data_t *) data; 255 const struct tp_finger *f = dev->tp_data->finger;
310 256 const int fingers = (size - 26) / 28;
311 if (nfinger) { 257 struct tp_state *s = &dev->tp_state;
312 *abs_x = int2bound(&cfg->x, raw2int(tp->finger->abs_x) - cfg->x.devmin); 258
313 *abs_y = int2bound(&cfg->y, cfg->y.devmax - raw2int(tp->finger->abs_y)); 259 if (size < 26 || (size - 26) % 28 != 0)
314 *rel_x = int2scale(&cfg->x, raw2int(tp->finger->rel_x)); 260 return -EIO;
315 *rel_y = int2scale(&cfg->y, -raw2int(tp->finger->rel_y)); 261
316 *pressure = int2bound(&cfg->p, raw2int(tp->finger->force_major)); 262 if (!fingers) {
317 *width = int2bound(&cfg->w, raw2int(tp->finger->size_major)); 263 s->pressure = 0;
318 } else { 264 s->fingers = 0;
319 *abs_x = 0; 265 return 0;
320 *abs_y = 0; 266 }
321 *rel_x = 0; 267
322 *rel_y = 0; 268 dprintk(9, "bcm5974: p: %+05d w: %+05d x: %+05d y: %+05d f: %d\n",
323 *pressure = 0; 269 raw2int(f->force_major), raw2int(f->size_major),
324 *width = 0; 270 raw2int(f->abs_x), raw2int(f->abs_y), fingers);
325 } 271
326 272 s->pressure = int2bound(&c->p, raw2int(f->force_major));
327 /* report zero fingers for zero pressure */ 273 s->width = int2bound(&c->w, raw2int(f->size_major));
328 return *pressure > 0?nfinger:0; 274 s->abs_x = int2bound(&c->x, raw2int(f->abs_x) - c->x.devmin);
275 s->abs_y = int2bound(&c->y, c->y.devmax - raw2int(f->abs_y));
276 s->fingers = s->pressure > 0 ? fingers : 0;
277
278 return 0;
329} 279}
330 280
331static void atp_button(struct urb *urb) 281/* Wellspring initialization constants */
282#define ATP_WELLSPRING_MODE_READ_REQUEST_ID 1
283#define ATP_WELLSPRING_MODE_WRITE_REQUEST_ID 9
284#define ATP_WELLSPRING_MODE_REQUEST_VALUE 0x300
285#define ATP_WELLSPRING_MODE_REQUEST_INDEX 0
286#define ATP_WELLSPRING_MODE_VENDOR_VALUE_1 0x01
287#define ATP_WELLSPRING_MODE_VENDOR_VALUE_2 0x05
288
289static int atp_wellspring_init(struct atp *dev)
332{ 290{
333 struct atp *dev = urb->context; 291 char *data = kmalloc(8, GFP_KERNEL);
334 int button, retval; 292 int error = 0, size;
335 293
336 switch (urb->status) { 294 if (!data) {
337 case 0: 295 err("bcm5974: out of memory");
338 break; 296 error = -ENOMEM;
339 case -EOVERFLOW: 297 goto error;
340 case -ECONNRESET: 298 }
341 case -ENOENT: 299
342 case -ESHUTDOWN: 300 /* reset button endpoint */
343 dbg("bcm5974: button urb shutting down: %d", urb->status); 301 if (usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
344 return; 302 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
345 default: 303 0, dev->cfg.bt_ep, NULL, 0, 5000)) {
346 dbg("bcm5974: button urb status: %d", urb->status); 304 err("bcm5974: could not reset button endpoint");
347 goto exit; 305 error = -EIO;
348 } 306 goto error;
349 307 }
350 /* drop incomplete datasets */ 308
351 if (dev->bt_urb->actual_length != 4) { 309 /* reset trackpad endpoint */
352 dprintk("bcm5974: incomplete button package (first byte: %d, length: %d)\n", 310 if (usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
353 (int)dev->bt_data[0], dev->bt_urb->actual_length); 311 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
354 goto exit; 312 0, dev->cfg.tp_ep, NULL, 0, 5000)) {
355 } 313 err("bcm5974: could not reset trackpad endpoint");
356 314 error = -EIO;
357 button = dev->bt_data[1]; 315 goto error;
358 316 }
359 /* only report button state changes */ 317
360 if (button != dev->bt_state) { 318 /* read configuration */
361 input_report_key(dev->input, BTN_LEFT, button); 319 size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
362 input_sync(dev->input); 320 ATP_WELLSPRING_MODE_READ_REQUEST_ID,
363 } 321 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
364 322 ATP_WELLSPRING_MODE_REQUEST_VALUE,
365 dev->bt_state = button; 323 ATP_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000);
366 324
367 exit: 325 if (size != 8) {
368 retval = usb_submit_urb(dev->bt_urb, GFP_ATOMIC); 326 err("bcm5974: could not read from device");
369 if (retval) 327 error = -EIO;
370 err("bcm5974: button urb failed: %d", retval); 328 goto error;
329 }
330
331 /* apply the mode switch */
332 data[0] = ATP_WELLSPRING_MODE_VENDOR_VALUE_1;
333 data[1] = ATP_WELLSPRING_MODE_VENDOR_VALUE_2;
334
335 /* write configuration */
336 size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
337 ATP_WELLSPRING_MODE_WRITE_REQUEST_ID,
338 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
339 ATP_WELLSPRING_MODE_REQUEST_VALUE,
340 ATP_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000);
341
342 if (size != 8) {
343 err("bcm5974: could not write to device");
344 error = -EIO;
345 goto error;
346 }
347
348 dev->tp_valid = 0;
349
350 printk(KERN_INFO "bcm5974: Wellspring mode initialized.\n");
351
352 kfree(data);
353 return 0;
354
355error:
356 kfree(data);
357 return error;
371} 358}
372 359
373static void atp_trackpad(struct urb *urb) 360static void irq_button(struct urb *urb)
374{ 361{
375 struct atp *dev = urb->context; 362 struct atp *dev = urb->context;
376 int abs_x, abs_y, rel_x, rel_y, pressure, width; 363 int error;
377 int quality, nfinger, retval; 364
378 365 switch (urb->status) {
379 switch (urb->status) { 366 case 0:
380 case 0: 367 break;
381 break; 368 case -EOVERFLOW:
382 case -EOVERFLOW: 369 case -ECONNRESET:
383 case -ECONNRESET: 370 case -ENOENT:
384 case -ENOENT: 371 case -ESHUTDOWN:
385 case -ESHUTDOWN: 372 dbg("bcm5974: button urb shutting down: %d", urb->status);
386 dbg("bcm5974: trackpad urb shutting down: %d", urb->status); 373 return;
387 return; 374 default:
388 default: 375 dbg("bcm5974: button urb status: %d", urb->status);
389 dbg("bcm5974: trackpad urb status: %d", urb->status); 376 goto exit;
390 goto exit; 377 }
391 } 378
392 379 if (compute_bt_state(dev, dev->bt_urb->actual_length)) {
393 /* first sample data ignored */ 380 dprintk(1, "bcm5974: bad button package, length: %d)\n",
394 if (!dev->tp_valid) { 381 dev->bt_urb->actual_length);
395 dev->tp_valid = 1; 382 goto exit;
396 goto exit; 383 }
397 } 384
398 385 /* only report button state changes */
399 /* determine quality of reading */ 386 if (dev->bt_state != dev->bt_prev_state) {
400 quality = compute_quality(dev->tp_data, dev->tp_urb->actual_length); 387 input_report_key(dev->input, BTN_LEFT, dev->bt_data->button);
401 388 input_sync(dev->input);
402 /* drop incomplete datasets */ 389 }
403 if (quality < 0) { 390
404 dprintk("bcm5974: incomplete trackpad package " 391exit:
405 "(first byte: %d, length: %d)\n", 392 error = usb_submit_urb(dev->bt_urb, GFP_ATOMIC);
406 (int)dev->tp_data[0], dev->tp_urb->actual_length); 393 if (error)
407 goto exit; 394 err("bcm5974: button urb failed: %d", error);
408 }
409
410 /* drop poor quality readings */
411 if (quality == 0)
412 goto exit;
413
414 nfinger = compute_movement(&abs_x, &abs_y,
415 &rel_x, &rel_y,
416 &pressure, &width,
417 &dev->cfg,
418 dev->tp_data, dev->tp_urb->actual_length);
419
420 if (debug > 1) {
421 printk(KERN_DEBUG "bcm5974: x: %04d y: %04d "
422 "dx: %3d dy: %3d p: %3d w: %3d\n",
423 abs_x, abs_y, rel_x, rel_y, pressure, width);
424 }
425
426 input_report_abs(dev->input, ABS_X, abs_x);
427 input_report_abs(dev->input, ABS_Y, abs_y);
428 input_report_abs(dev->input, ABS_PRESSURE, pressure);
429 input_report_abs(dev->input, ABS_TOOL_WIDTH, width);
430 input_report_key(dev->input, BTN_TOOL_FINGER, nfinger == 1);
431 input_report_key(dev->input, BTN_TOOL_DOUBLETAP, nfinger == 2);
432 input_report_key(dev->input, BTN_TOOL_TRIPLETAP, nfinger > 2);
433 input_sync(dev->input);
434
435 exit:
436 retval = usb_submit_urb(dev->tp_urb, GFP_ATOMIC);
437 if (retval)
438 err("bcm5974: trackpad urb failed: %d", retval);
439} 395}
440 396
441static int atp_open(struct input_dev *input) 397static void irq_trackpad(struct urb *urb)
442{ 398{
443 struct atp *dev = input_get_drvdata(input); 399 struct atp *dev = urb->context;
444 400 struct tp_state *state = &dev->tp_state;
445 if (!dev->open) { 401 int error;
446 if (usb_submit_urb(dev->bt_urb, GFP_ATOMIC)) 402
447 goto error; 403 switch (urb->status) {
448 if (usb_submit_urb(dev->tp_urb, GFP_ATOMIC)) 404 case 0:
449 goto err_free_bt_urb; 405 break;
450 } 406 case -EOVERFLOW:
451 407 case -ECONNRESET:
452 dev->open = 1; 408 case -ENOENT:
453 dev->suspended = 0; 409 case -ESHUTDOWN:
454 dev->tp_valid = 0; 410 dbg("bcm5974: trackpad urb shutting down: %d", urb->status);
455 411 return;
456 return 0; 412 default:
413 dbg("bcm5974: trackpad urb status: %d", urb->status);
414 goto exit;
415 }
416
417 /* first sample data ignored */
418 if (!dev->tp_valid) {
419 dev->tp_valid = 1;
420 goto exit;
421 }
422
423 if (compute_tp_state(dev, dev->tp_urb->actual_length)) {
424 dprintk(1, "bcm5974: bad trackpad package, length: %d)\n",
425 dev->tp_urb->actual_length);
426 goto exit;
427 }
428
429 input_report_abs(dev->input, ABS_PRESSURE, state->pressure);
430 input_report_abs(dev->input, ABS_TOOL_WIDTH, state->width);
431 input_report_abs(dev->input, ABS_X, state->abs_x);
432 input_report_abs(dev->input, ABS_Y, state->abs_y);
433 input_report_key(dev->input, BTN_TOOL_FINGER, state->fingers == 1);
434 input_report_key(dev->input, BTN_TOOL_DOUBLETAP, state->fingers == 2);
435 input_report_key(dev->input, BTN_TOOL_TRIPLETAP, state->fingers > 2);
436 input_sync(dev->input);
437
438exit:
439 error = usb_submit_urb(dev->tp_urb, GFP_ATOMIC);
440 if (error)
441 err("bcm5974: trackpad urb failed: %d", error);
442}
457 443
458 err_free_bt_urb: 444static int atp_open(struct input_dev *input)
459 usb_free_urb(dev->bt_urb); 445{
460 error: 446 struct atp *dev = input_get_drvdata(input);
461 return -EIO; 447
448 if (!dev->open) {
449 if (usb_submit_urb(dev->bt_urb, GFP_ATOMIC))
450 goto error;
451 if (usb_submit_urb(dev->tp_urb, GFP_ATOMIC))
452 goto err_free_bt_urb;
453 }
454
455 dev->open = 1;
456 dev->suspended = 0;
457 return 0;
458
459err_free_bt_urb:
460 usb_free_urb(dev->bt_urb);
461error:
462 return -EIO;
462} 463}
463 464
464static void atp_close(struct input_dev *input) 465static void atp_close(struct input_dev *input)
465{ 466{
466 struct atp *dev = input_get_drvdata(input); 467 struct atp *dev = input_get_drvdata(input);
467 468
468 if (dev->open && !dev->suspended) { 469 usb_kill_urb(dev->tp_urb);
469 usb_kill_urb(dev->tp_urb); 470 usb_kill_urb(dev->bt_urb);
470 usb_kill_urb(dev->bt_urb);
471 }
472 471
473 dev->open = 0; 472 dev->open = 0;
474 dev->suspended = 0; 473 dev->suspended = 0;
475} 474}
476 475
477static int atp_probe(struct usb_interface *iface, 476static int atp_probe(struct usb_interface *iface,
478 const struct usb_device_id *id) 477 const struct usb_device_id *id)
479{ 478{
480 int error = -ENOMEM; 479 struct usb_device *udev = interface_to_usbdev(iface);
481 struct usb_device *udev = interface_to_usbdev(iface); 480 const struct atp_config *cfg;
482 const struct atp_config_t *cfg; 481 struct atp *dev;
483 struct atp *dev; 482 struct input_dev *input_dev;
484 struct input_dev *input_dev; 483 int error = 0;
485 484
486 printk(KERN_INFO "bcm5974: Probing device...\n"); 485 /* find the product index */
487 486 cfg = atp_product_config(udev);
488 /* find the product index */ 487
489 cfg = atp_product_config(udev); 488 /* allocate memory for our device state and initialize it */
490 489 dev = kzalloc(sizeof(struct atp), GFP_KERNEL);
491 /* allocate memory for our device state and initialize it */ 490 input_dev = input_allocate_device();
492 dev = kzalloc(sizeof(struct atp), GFP_KERNEL); 491 if (!dev || !input_dev) {
493 input_dev = input_allocate_device(); 492 err("bcm5974: out of memory");
494 if (!dev || !input_dev) { 493 error = -ENOMEM;
495 err("Out of memory"); 494 goto err_free_devs;
496 goto err_free_devs; 495 }
497 } 496
498 497 dev->udev = udev;
499 dev->udev = udev; 498 dev->input = input_dev;
500 dev->input = input_dev; 499 dev->cfg = *cfg;
501 dev->cfg = *cfg; 500
502 501 /* switch to raw sensor mode */
503 /* switch to raw sensor mode */ 502 if (atp_wellspring_init(dev)) {
504 if (atp_wellspring_init(udev)) 503 error = -EIO;
505 goto err_free_devs; 504 goto err_free_devs;
506 505 }
507 dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL); 506
508 if (!dev->bt_urb) 507 dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL);
509 goto err_free_devs; 508 if (!dev->bt_urb) {
510 509 error = -ENOMEM;
511 dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL); 510 goto err_free_devs;
512 if (!dev->tp_urb) 511 }
513 goto err_free_bt_urb; 512
514 513 dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL);
515 dev->bt_data = usb_buffer_alloc(dev->udev, 514 if (!dev->tp_urb) {
516 dev->cfg.bt_datalen, 515 error = -ENOMEM;
517 GFP_KERNEL, 516 goto err_free_bt_urb;
518 &dev->bt_urb->transfer_dma); 517 }
519 if (!dev->bt_data) 518
520 goto err_free_urb; 519 dev->bt_data = usb_buffer_alloc(dev->udev,
521 520 dev->cfg.bt_datalen, GFP_KERNEL,
522 dev->tp_data = usb_buffer_alloc(dev->udev, 521 &dev->bt_urb->transfer_dma);
523 dev->cfg.tp_datalen, 522 if (!dev->bt_data) {
524 GFP_KERNEL, 523 error = -ENOMEM;
525 &dev->tp_urb->transfer_dma); 524 goto err_free_urb;
526 if (!dev->tp_data) 525 }
527 goto err_free_bt_buffer; 526
528 527 dev->tp_data = usb_buffer_alloc(dev->udev,
529 usb_fill_int_urb(dev->bt_urb, udev, 528 dev->cfg.tp_datalen, GFP_KERNEL,
530 usb_rcvintpipe(udev, cfg->bt_ep), 529 &dev->tp_urb->transfer_dma);
531 dev->bt_data, dev->cfg.bt_datalen, 530 if (!dev->tp_data) {
532 atp_button, dev, 1); 531 error = -ENOMEM;
533 532 goto err_free_bt_buffer;
534 usb_fill_int_urb(dev->tp_urb, udev, 533 }
535 usb_rcvintpipe(udev, cfg->tp_ep), 534
536 dev->tp_data, dev->cfg.tp_datalen, 535 usb_fill_int_urb(dev->bt_urb, udev,
537 atp_trackpad, dev, 1); 536 usb_rcvintpipe(udev, cfg->bt_ep),
538 537 dev->bt_data, dev->cfg.bt_datalen,
539 usb_make_path(udev, dev->phys, sizeof(dev->phys)); 538 irq_button, dev, 1);
540 strlcat(dev->phys, "/input0", sizeof(dev->phys)); 539
541 540 usb_fill_int_urb(dev->tp_urb, udev,
542 input_dev->name = "bcm5974"; 541 usb_rcvintpipe(udev, cfg->tp_ep),
543 input_dev->phys = dev->phys; 542 dev->tp_data, dev->cfg.tp_datalen,
544 usb_to_input_id(dev->udev, &input_dev->id); 543 irq_trackpad, dev, 1);
545 input_dev->dev.parent = &iface->dev; 544
546 545 usb_make_path(udev, dev->phys, sizeof(dev->phys));
547 input_set_drvdata(input_dev, dev); 546 strlcat(dev->phys, "/input0", sizeof(dev->phys));
548 547
549 input_dev->open = atp_open; 548 input_dev->name = "bcm5974";
550 input_dev->close = atp_close; 549 input_dev->phys = dev->phys;
551 550 usb_to_input_id(dev->udev, &input_dev->id);
552 set_bit(EV_ABS, input_dev->evbit); 551 input_dev->dev.parent = &iface->dev;
553 input_set_abs_params(input_dev, ABS_X, 552
554 cfg->x.min, cfg->x.max, cfg->x.fuzz, cfg->x.flat); 553 input_set_drvdata(input_dev, dev);
555 input_set_abs_params(input_dev, ABS_Y, 554
556 cfg->y.min, cfg->y.max, cfg->y.fuzz, cfg->y.flat); 555 input_dev->open = atp_open;
557 input_set_abs_params(input_dev, ABS_PRESSURE, 556 input_dev->close = atp_close;
558 cfg->p.min, cfg->p.max, cfg->p.fuzz, cfg->p.flat); 557
559 input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 558 set_bit(EV_ABS, input_dev->evbit);
560 cfg->w.min, cfg->w.max, cfg->w.fuzz, cfg->w.flat); 559 input_set_abs_params(input_dev, ABS_PRESSURE,
561 560 0, cfg->p.dim, cfg->p.dim / SNRATIO, 0);
562 set_bit(EV_KEY, input_dev->evbit); 561 input_set_abs_params(input_dev, ABS_TOOL_WIDTH,
563 set_bit(BTN_TOOL_FINGER, input_dev->keybit); 562 0, cfg->w.dim, cfg->w.dim / SNRATIO, 0);
564 set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); 563 input_set_abs_params(input_dev, ABS_X,
565 set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); 564 0, cfg->x.dim, cfg->x.dim / SNRATIO, 0);
566 set_bit(BTN_LEFT, input_dev->keybit); 565 input_set_abs_params(input_dev, ABS_Y,
567 566 0, cfg->y.dim, cfg->y.dim / SNRATIO, 0);
568 error = input_register_device(dev->input); 567
569 if (error) 568 set_bit(EV_KEY, input_dev->evbit);
570 goto err_free_buffer; 569 set_bit(BTN_TOOL_FINGER, input_dev->keybit);
571 570 set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
572 /* save our data pointer in this interface device */ 571 set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
573 usb_set_intfdata(iface, dev); 572 set_bit(BTN_LEFT, input_dev->keybit);
574 573
575 return 0; 574 error = input_register_device(dev->input);
576 575 if (error)
577 err_free_buffer: 576 goto err_free_buffer;
578 usb_buffer_free(dev->udev, dev->cfg.tp_datalen, 577
579 dev->tp_data, dev->tp_urb->transfer_dma); 578 /* save our data pointer in this interface device */
580 err_free_bt_buffer: 579 usb_set_intfdata(iface, dev);
581 usb_buffer_free(dev->udev, dev->cfg.bt_datalen, 580
582 dev->bt_data, dev->bt_urb->transfer_dma); 581 return 0;
583 err_free_urb: 582
584 usb_free_urb(dev->tp_urb); 583err_free_buffer:
585 err_free_bt_urb: 584 usb_buffer_free(dev->udev, dev->cfg.tp_datalen,
586 usb_free_urb(dev->bt_urb); 585 dev->tp_data, dev->tp_urb->transfer_dma);
587 err_free_devs: 586err_free_bt_buffer:
588 usb_set_intfdata(iface, NULL); 587 usb_buffer_free(dev->udev, dev->cfg.bt_datalen,
589 kfree(dev); 588 dev->bt_data, dev->bt_urb->transfer_dma);
590 input_free_device(input_dev); 589err_free_urb:
591 return error; 590 usb_free_urb(dev->tp_urb);
591err_free_bt_urb:
592 usb_free_urb(dev->bt_urb);
593err_free_devs:
594 usb_set_intfdata(iface, NULL);
595 kfree(dev);
596 input_free_device(input_dev);
597 return error;
592} 598}
593 599
594static void atp_disconnect(struct usb_interface *iface) 600static void atp_disconnect(struct usb_interface *iface)
595{ 601{
596 struct atp *dev = usb_get_intfdata(iface); 602 struct atp *dev = usb_get_intfdata(iface);
597 603
598 usb_set_intfdata(iface, NULL); 604 usb_set_intfdata(iface, NULL);
599 if (dev) { 605
600 input_unregister_device(dev->input); 606 if (dev) {
601 usb_buffer_free(dev->udev, dev->cfg.tp_datalen, 607 input_unregister_device(dev->input);
602 dev->tp_data, dev->tp_urb->transfer_dma); 608 usb_buffer_free(dev->udev, dev->cfg.tp_datalen,
603 usb_buffer_free(dev->udev, dev->cfg.bt_datalen, 609 dev->tp_data, dev->tp_urb->transfer_dma);
604 dev->bt_data, dev->bt_urb->transfer_dma); 610 usb_buffer_free(dev->udev, dev->cfg.bt_datalen,
605 usb_free_urb(dev->tp_urb); 611 dev->bt_data, dev->bt_urb->transfer_dma);
606 usb_free_urb(dev->bt_urb); 612 usb_free_urb(dev->tp_urb);
607 kfree(dev); 613 usb_free_urb(dev->bt_urb);
608 } 614 kfree(dev);
609 printk(KERN_INFO "bcm5974: disconnected\n"); 615 }
616
617 printk(KERN_INFO "bcm5974: disconnected\n");
610} 618}
611 619
612static int atp_suspend(struct usb_interface *iface, pm_message_t message) 620static int atp_suspend(struct usb_interface *iface, pm_message_t message)
613{ 621{
614 struct atp *dev = usb_get_intfdata(iface); 622 struct atp *dev = usb_get_intfdata(iface);
615 623
616 if (dev->open && !dev->suspended++) { 624 if (dev) {
617 usb_kill_urb(dev->tp_urb); 625 if (!dev->suspended)
618 usb_kill_urb(dev->bt_urb); 626 atp_close(dev->input);
619 } 627 dev->suspended++;
628 }
620 629
621 return 0; 630 return 0;
622} 631}
623 632
624static int atp_resume(struct usb_interface *iface) 633static int atp_resume(struct usb_interface *iface)
625{ 634{
626 struct atp *dev = usb_get_intfdata(iface); 635 struct atp *dev = usb_get_intfdata(iface);
627 636 int error = 0;
628 if (dev->open && !--dev->suspended) { 637
629 if (usb_submit_urb(dev->bt_urb, GFP_ATOMIC)) 638 if (dev && dev->suspended) {
630 goto error; 639 if (!--dev->suspended)
631 if (usb_submit_urb(dev->tp_urb, GFP_ATOMIC)) 640 error = atp_open(dev->input);
632 goto err_free_bt_urb; 641 }
633 } 642
634 643 return error;
635 dev->tp_valid = 0;
636 return 0;
637
638 err_free_bt_urb:
639 usb_free_urb(dev->bt_urb);
640 error:
641 return -EIO;
642} 644}
643 645
644static int atp_reset_resume(struct usb_interface *iface) 646static int atp_reset_resume(struct usb_interface *iface)
645{ 647{
646 struct atp *dev = usb_get_intfdata(iface); 648 struct atp *dev = usb_get_intfdata(iface);
647 649
648 if (dev->suspended == 1) { 650 if (dev && atp_wellspring_init(dev))
649 if (atp_wellspring_init(dev->udev)) 651 printk(KERN_INFO "bcm5974: warning: reset failed\n");
650 printk(KERN_INFO "bcm5974: warning: reset failed\n");
651 }
652 652
653 return atp_resume(iface); 653 return atp_resume(iface);
654} 654}
655 655
656static int atp_pre_reset(struct usb_interface *iface) 656static int atp_pre_reset(struct usb_interface *iface)
657{ 657{
658 return atp_suspend(iface, PMSG_ON); 658 return atp_suspend(iface, PMSG_ON);
659} 659}
660 660
661static int atp_post_reset(struct usb_interface *iface) 661static int atp_post_reset(struct usb_interface *iface)
662{ 662{
663 return atp_reset_resume(iface); 663 return atp_reset_resume(iface);
664} 664}
665 665
666static struct usb_driver atp_driver = { 666static struct usb_driver atp_driver = {
667 .name = "bcm5974", 667 .name = "bcm5974",
668 .probe = atp_probe, 668 .probe = atp_probe,
669 .disconnect = atp_disconnect, 669 .disconnect = atp_disconnect,
670 .suspend = atp_suspend, 670 .suspend = atp_suspend,
671 .resume = atp_resume, 671 .resume = atp_resume,
672 .reset_resume = atp_reset_resume, 672 .reset_resume = atp_reset_resume,
673 .pre_reset = atp_pre_reset, 673 .pre_reset = atp_pre_reset,
674 .post_reset = atp_post_reset, 674 .post_reset = atp_post_reset,
675 .id_table = atp_table, 675 .id_table = atp_table,
676}; 676};
677 677
678static int __init atp_init(void) 678static int __init atp_init(void)
679{ 679{
680 return usb_register(&atp_driver); 680 return usb_register(&atp_driver);
681} 681}
682 682
683static void __exit atp_exit(void) 683static void __exit atp_exit(void)
684{ 684{
685 usb_deregister(&atp_driver); 685 usb_deregister(&atp_driver);
686} 686}
687 687
688module_init(atp_init); 688module_init(atp_init);
689module_exit(atp_exit); 689module_exit(atp_exit);
690