summaryrefslogtreecommitdiff
path: root/bcm5974.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2008-10-08 23:39:23 +0200
committerHenrik Rydberg <rydberg@euromail.se>2008-10-08 23:39:23 +0200
commit262c292d2d4241301476dbbefffe0b1ff827f2b2 (patch)
tree7f8eddcf6e47f23fce15179df9c46a1df9f7b0bd /bcm5974.c
parent6e62e2ecb58e6a1982b22b4e9c948483ac70ba34 (diff)
parentaa2d0bf085f624ad24deb0357d4fe935225ccd18 (diff)
Merge branch 'master' into detour
Diffstat (limited to 'bcm5974.c')
-rw-r--r--bcm5974.c667
1 files changed, 352 insertions, 315 deletions
diff --git a/bcm5974.c b/bcm5974.c
index a7f070f..bf6c59f 100644
--- a/bcm5974.c
+++ b/bcm5974.c
@@ -39,42 +39,43 @@
39#include <linux/module.h> 39#include <linux/module.h>
40#include <linux/usb/input.h> 40#include <linux/usb/input.h>
41#include <linux/hid.h> 41#include <linux/hid.h>
42#include <linux/mutex.h>
42 43
43#define APPLE_VENDOR_ID 0x05AC 44#define USB_VENDOR_ID_APPLE 0x05ac
44 45
45/* MacbookAir, aka wellspring */ 46/* MacbookAir, aka wellspring */
46#define ATP_WELLSPRING_ANSI 0x0223 47#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223
47#define ATP_WELLSPRING_ISO 0x0224 48#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224
48#define ATP_WELLSPRING_JIS 0x0225 49#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225
49/* MacbookProPenryn, aka wellspring2 */ 50/* MacbookProPenryn, aka wellspring2 */
50#define ATP_WELLSPRING2_ANSI 0x0230 51#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
51#define ATP_WELLSPRING2_ISO 0x0231 52#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
52#define ATP_WELLSPRING2_JIS 0x0232 53#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
53 54
54#define ATP_DEVICE(prod) { \ 55#define BCM5974_DEVICE(prod) { \
55 .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ 56 .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \
56 USB_DEVICE_ID_MATCH_INT_CLASS | \ 57 USB_DEVICE_ID_MATCH_INT_CLASS | \
57 USB_DEVICE_ID_MATCH_INT_PROTOCOL), \ 58 USB_DEVICE_ID_MATCH_INT_PROTOCOL), \
58 .idVendor = APPLE_VENDOR_ID, \ 59 .idVendor = USB_VENDOR_ID_APPLE, \
59 .idProduct = (prod), \ 60 .idProduct = (prod), \
60 .bInterfaceClass = USB_INTERFACE_CLASS_HID, \ 61 .bInterfaceClass = USB_INTERFACE_CLASS_HID, \
61 .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE \ 62 .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE \
62} 63}
63 64
64/* table of devices that work with this driver */ 65/* table of devices that work with this driver */
65static const struct usb_device_id atp_table [] = { 66static const struct usb_device_id bcm5974_table[] = {
66 /* MacbookAir1.1 */ 67 /* MacbookAir1.1 */
67 ATP_DEVICE(ATP_WELLSPRING_ANSI), 68 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
68 ATP_DEVICE(ATP_WELLSPRING_ISO), 69 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
69 ATP_DEVICE(ATP_WELLSPRING_JIS), 70 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_JIS),
70 /* MacbookProPenryn */ 71 /* MacbookProPenryn */
71 ATP_DEVICE(ATP_WELLSPRING2_ANSI), 72 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
72 ATP_DEVICE(ATP_WELLSPRING2_ISO), 73 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
73 ATP_DEVICE(ATP_WELLSPRING2_JIS), 74 BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
74 /* Terminating entry */ 75 /* Terminating entry */
75 {} 76 {}
76}; 77};
77MODULE_DEVICE_TABLE(usb, atp_table); 78MODULE_DEVICE_TABLE(usb, bcm5974_table);
78 79
79MODULE_AUTHOR("Henrik Rydberg"); 80MODULE_AUTHOR("Henrik Rydberg");
80MODULE_DESCRIPTION("Apple USB BCM5974 multitouch driver"); 81MODULE_DESCRIPTION("Apple USB BCM5974 multitouch driver");
@@ -104,7 +105,7 @@ struct tp_header {
104 105
105/* trackpad finger structure */ 106/* trackpad finger structure */
106struct tp_finger { 107struct tp_finger {
107 __le16 origin; /* left/right origin? */ 108 __le16 origin; /* zero when switching track finger */
108 __le16 abs_x; /* absolute x coodinate */ 109 __le16 abs_x; /* absolute x coodinate */
109 __le16 abs_y; /* absolute y coodinate */ 110 __le16 abs_y; /* absolute y coodinate */
110 __le16 rel_x; /* relative x coodinate */ 111 __le16 rel_x; /* relative x coodinate */
@@ -125,50 +126,40 @@ struct tp_data {
125}; 126};
126 127
127/* device-specific parameters */ 128/* device-specific parameters */
128struct atp_params { 129struct bcm5974_param {
129 int dim; /* logical dimension */ 130 int dim; /* logical dimension */
131 int fuzz; /* logical noise value */
130 int devmin; /* device minimum reading */ 132 int devmin; /* device minimum reading */
131 int devmax; /* device maximum reading */ 133 int devmax; /* device maximum reading */
132}; 134};
133 135
134/* device-specific configuration */ 136/* device-specific configuration */
135struct atp_config { 137struct bcm5974_config {
136 int ansi, iso, jis; /* the product id of this device */ 138 int ansi, iso, jis; /* the product id of this device */
137 int bt_ep; /* the endpoint of the button interface */ 139 int bt_ep; /* the endpoint of the button interface */
138 int bt_datalen; /* data length of the button interface */ 140 int bt_datalen; /* data length of the button interface */
139 int tp_ep; /* the endpoint of the trackpad interface */ 141 int tp_ep; /* the endpoint of the trackpad interface */
140 int tp_datalen; /* data length of the trackpad interface */ 142 int tp_datalen; /* data length of the trackpad interface */
141 struct atp_params p; /* finger pressure limits */ 143 struct bcm5974_param p; /* finger pressure limits */
142 struct atp_params w; /* finger width limits */ 144 struct bcm5974_param w; /* finger width limits */
143 struct atp_params x; /* horizontal limits */ 145 struct bcm5974_param x; /* horizontal limits */
144 struct atp_params y; /* vertical limits */ 146 struct bcm5974_param y; /* vertical limits */
145};
146
147/* logical trackpad state */
148struct tp_state {
149 int pressure; /* finger pressure value */
150 int width; /* finger width value */
151 int abs_x; /* absolute x coordinate */
152 int abs_y; /* absolute y coordinate */
153 int fingers; /* number of fingers on trackpad */
154}; 147};
155 148
156/* logical device structure */ 149/* logical device structure */
157struct atp { 150struct bcm5974 {
158 char phys[64]; 151 char phys[64];
159 struct usb_device *udev; /* usb device */ 152 struct usb_device *udev; /* usb device */
153 struct usb_interface *intf; /* our interface */
160 struct input_dev *input; /* input dev */ 154 struct input_dev *input; /* input dev */
161 struct atp_config cfg; /* device configuration */ 155 struct bcm5974_config cfg; /* device configuration */
162 int open; /* >0: open, else closed */ 156 struct mutex pm_mutex; /* serialize access to open/suspend */
163 int suspended; /* >0: suspended, else open */ 157 int opened; /* 1: opened, 0: closed */
164 struct urb *bt_urb; /* button usb request block */ 158 struct urb *bt_urb; /* button usb request block */
165 struct bt_data *bt_data; /* button transferred data */ 159 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 */ 160 struct urb *tp_urb; /* trackpad usb request block */
169 struct tp_data *tp_data; /* trackpad transferred data */ 161 struct tp_data *tp_data; /* trackpad transferred data */
170 struct tp_state tp_state; /* logical trackpad state */ 162 int fingers; /* number of fingers on trackpad */
171 unsigned tp_valid; /* trackpad sensors valid */
172}; 163};
173 164
174/* logical dimensions */ 165/* logical dimensions */
@@ -176,45 +167,54 @@ struct atp {
176#define DIM_WIDTH 16 /* maximum finger width */ 167#define DIM_WIDTH 16 /* maximum finger width */
177#define DIM_X 1280 /* maximum trackpad x value */ 168#define DIM_X 1280 /* maximum trackpad x value */
178#define DIM_Y 800 /* maximum trackpad y value */ 169#define DIM_Y 800 /* maximum trackpad y value */
179#define SNRATIO 50 /* signal to noise ratio */ 170
171/* logical signal quality */
172#define SN_PRESSURE 45 /* pressure signal-to-noise ratio */
173#define SN_WIDTH 100 /* width signal-to-noise ratio */
174#define SN_COORD 250 /* coordinate signal-to-noise ratio */
175
176/* pressure thresholds */
177#define PRESSURE_LOW (2 * DIM_PRESSURE / SN_PRESSURE)
178#define PRESSURE_HIGH (3 * PRESSURE_LOW)
180 179
181/* device constants */ 180/* device constants */
182static const struct atp_config atp_config_table[] = { 181static const struct bcm5974_config bcm5974_config_table[] = {
183 { 182 {
184 ATP_WELLSPRING_ANSI, 183 USB_DEVICE_ID_APPLE_WELLSPRING_ANSI,
185 ATP_WELLSPRING_ISO, 184 USB_DEVICE_ID_APPLE_WELLSPRING_ISO,
186 ATP_WELLSPRING_JIS, 185 USB_DEVICE_ID_APPLE_WELLSPRING_JIS,
187 0x84, sizeof(struct bt_data), 186 0x84, sizeof(struct bt_data),
188 0x81, sizeof(struct tp_data), 187 0x81, sizeof(struct tp_data),
189 { DIM_PRESSURE, 0, 256 }, 188 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
190 { DIM_WIDTH, 0, 2048 }, 189 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
191 { DIM_X, -4824, 5342 }, 190 { DIM_X, DIM_X / SN_COORD, -4824, 5342 },
192 { DIM_Y, -172, 5820 } 191 { DIM_Y, DIM_Y / SN_COORD, -172, 5820 }
193 }, 192 },
194 { 193 {
195 ATP_WELLSPRING2_ANSI, 194 USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI,
196 ATP_WELLSPRING2_ISO, 195 USB_DEVICE_ID_APPLE_WELLSPRING2_ISO,
197 ATP_WELLSPRING2_JIS, 196 USB_DEVICE_ID_APPLE_WELLSPRING2_JIS,
198 0x84, sizeof(struct bt_data), 197 0x84, sizeof(struct bt_data),
199 0x81, sizeof(struct tp_data), 198 0x81, sizeof(struct tp_data),
200 { DIM_PRESSURE, 0, 256 }, 199 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 },
201 { DIM_WIDTH, 0, 2048 }, 200 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 },
202 { DIM_X, -4824, 5342 }, 201 { DIM_X, DIM_X / SN_COORD, -4824, 4824 },
203 { DIM_Y, -172, 5820 } 202 { DIM_Y, DIM_Y / SN_COORD, -172, 4290 }
204 }, 203 },
205 {} 204 {}
206}; 205};
207 206
208/* return the device-specific configuration by device */ 207/* return the device-specific configuration by device */
209static const struct atp_config *atp_product_config(struct usb_device *udev) 208static const struct bcm5974_config *bcm5974_get_config(struct usb_device *udev)
210{ 209{
211 u16 id = le16_to_cpu(udev->descriptor.idProduct); 210 u16 id = le16_to_cpu(udev->descriptor.idProduct);
212 const struct atp_config *config; 211 const struct bcm5974_config *cfg;
213 for (config = atp_config_table; config->ansi; ++config) 212
214 if (config->ansi == id || config->iso == id || 213 for (cfg = bcm5974_config_table; cfg->ansi; ++cfg)
215 config->jis == id) 214 if (cfg->ansi == id || cfg->iso == id || cfg->jis == id)
216 return config; 215 return cfg;
217 return atp_config_table; 216
217 return bcm5974_config_table;
218} 218}
219 219
220/* convert 16-bit little endian to signed integer */ 220/* convert 16-bit little endian to signed integer */
@@ -224,142 +224,189 @@ static inline int raw2int(__le16 x)
224} 224}
225 225
226/* scale device data to logical dimensions (asserts devmin < devmax) */ 226/* scale device data to logical dimensions (asserts devmin < devmax) */
227static inline int int2scale(const struct atp_params *p, int x) 227static inline int int2scale(const struct bcm5974_param *p, int x)
228{ 228{
229 return x * p->dim / (p->devmax - p->devmin); 229 return x * p->dim / (p->devmax - p->devmin);
230} 230}
231 231
232/* all logical value ranges are [0,dim). */ 232/* all logical value ranges are [0,dim). */
233static inline int int2bound(const struct atp_params *p, int x) 233static inline int int2bound(const struct bcm5974_param *p, int x)
234{ 234{
235 int s = int2scale(p, x); 235 int s = int2scale(p, x);
236 return s < 0 ? 0 : s >= p->dim ? p->dim - 1 : s; 236
237 //return clamp_val(s, 0, p->dim - 1);
238 return s < 0 ? 0 : s >= p->dim ? p->dim - 1 : s;
237} 239}
238 240
239/* convert button data to logical button state */ 241/* setup which logical events to report */
240static int compute_bt_state(struct atp *dev, int size) 242static void setup_events_to_report(struct input_dev *input_dev,
243 const struct bcm5974_config *cfg)
244{
245 __set_bit(EV_ABS, input_dev->evbit);
246
247 input_set_abs_params(input_dev, ABS_PRESSURE,
248 0, cfg->p.dim, cfg->p.fuzz, 0);
249 input_set_abs_params(input_dev, ABS_TOOL_WIDTH,
250 0, cfg->w.dim, cfg->w.fuzz, 0);
251 input_set_abs_params(input_dev, ABS_X,
252 0, cfg->x.dim, cfg->x.fuzz, 0);
253 input_set_abs_params(input_dev, ABS_Y,
254 0, cfg->y.dim, cfg->y.fuzz, 0);
255
256 __set_bit(EV_KEY, input_dev->evbit);
257 __set_bit(BTN_TOUCH, input_dev->keybit);
258 __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
259 __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
260 __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
261 __set_bit(BTN_LEFT, input_dev->keybit);
262}
263
264/* report button data as logical button state */
265static int report_bt_state(struct bcm5974 *dev, int size)
241{ 266{
242 if (size != sizeof(struct bt_data)) 267 if (size != sizeof(struct bt_data))
243 return -EIO; 268 return -EIO;
244 269
245 dev->bt_prev_state = dev->bt_state; 270 input_report_key(dev->input, BTN_LEFT, dev->bt_data->button);
246 dev->bt_state = dev->bt_data->button; 271 input_sync(dev->input);
247 272
248 return 0; 273 return 0;
249} 274}
250 275
251/* convert trackpad data to logical trackpad state */ 276/* report trackpad data as logical trackpad state */
252static int compute_tp_state(struct atp *dev, int size) 277static int report_tp_state(struct bcm5974 *dev, int size)
253{ 278{
254 const struct atp_config *c = &dev->cfg; 279 const struct bcm5974_config *c = &dev->cfg;
255 const struct tp_finger *f = dev->tp_data->finger; 280 const struct tp_finger *f = dev->tp_data->finger;
281 struct input_dev *input = dev->input;
256 const int fingers = (size - 26) / 28; 282 const int fingers = (size - 26) / 28;
257 struct tp_state *s = &dev->tp_state; 283 int raw_p, raw_w, raw_x, raw_y;
284 int ptest = 0, origin = 0, nmin = 0, nmax = 0;
285 int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
258 286
259 if (size < 26 || (size - 26) % 28 != 0) 287 if (size < 26 || (size - 26) % 28 != 0)
260 return -EIO; 288 return -EIO;
261 289
262 if (!fingers) { 290 /* always track the first finger; when detached, start over */
263 s->pressure = 0; 291 if (fingers) {
264 s->fingers = 0; 292 raw_p = raw2int(f->force_major);
265 return 0; 293 raw_w = raw2int(f->size_major);
294 raw_x = raw2int(f->abs_x);
295 raw_y = raw2int(f->abs_y);
296
297 dprintk(9,
298 "bcm5974: raw: p: %+05d w: %+05d x: %+05d y: %+05d\n",
299 raw_p, raw_w, raw_x, raw_y);
300
301 ptest = int2bound(&c->p, raw_p);
302 origin = raw2int(f->origin);
303 }
304
305 /* while tracking finger still valid, count all fingers */
306 if (ptest > PRESSURE_LOW && origin) {
307 abs_p = ptest;
308 abs_w = int2bound(&c->w, raw_w);
309 abs_x = int2bound(&c->x, raw_x - c->x.devmin);
310 abs_y = int2bound(&c->y, c->y.devmax - raw_y);
311 for (; f != dev->tp_data->finger + fingers; f++) {
312 ptest = int2bound(&c->p, raw2int(f->force_major));
313 if (ptest > PRESSURE_LOW)
314 nmax++;
315 if (ptest > PRESSURE_HIGH)
316 nmin++;
317 }
266 } 318 }
267 319
268 dprintk(9, "bcm5974: p: %+05d w: %+05d x: %+05d y: %+05d f: %d\n", 320 if (dev->fingers < nmin)
269 raw2int(f->force_major), raw2int(f->size_major), 321 dev->fingers = nmin;
270 raw2int(f->abs_x), raw2int(f->abs_y), fingers); 322 if (dev->fingers > nmax)
323 dev->fingers = nmax;
324
325 input_report_key(input, BTN_TOUCH, dev->fingers > 0);
326 input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1);
327 input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2);
328 input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers > 2);
329
330 input_report_abs(input, ABS_PRESSURE, abs_p);
331 input_report_abs(input, ABS_TOOL_WIDTH, abs_w);
332
333 if (abs_p) {
334 input_report_abs(input, ABS_X, abs_x);
335 input_report_abs(input, ABS_Y, abs_y);
336
337 dprintk(8,
338 "bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d "
339 "nmin: %d nmax: %d n: %d\n",
340 abs_p, abs_w, abs_x, abs_y, nmin, nmax, dev->fingers);
271 341
272 s->pressure = int2bound(&c->p, raw2int(f->force_major)); 342 }
273 s->width = int2bound(&c->w, raw2int(f->size_major)); 343
274 s->abs_x = int2bound(&c->x, raw2int(f->abs_x) - c->x.devmin); 344 input_sync(input);
275 s->abs_y = int2bound(&c->y, c->y.devmax - raw2int(f->abs_y));
276 s->fingers = s->pressure > 0 ? fingers : 0;
277 345
278 return 0; 346 return 0;
279} 347}
280 348
281/* Wellspring initialization constants */ 349/* Wellspring initialization constants */
282#define ATP_WELLSPRING_MODE_READ_REQUEST_ID 1 350#define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID 1
283#define ATP_WELLSPRING_MODE_WRITE_REQUEST_ID 9 351#define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID 9
284#define ATP_WELLSPRING_MODE_REQUEST_VALUE 0x300 352#define BCM5974_WELLSPRING_MODE_REQUEST_VALUE 0x300
285#define ATP_WELLSPRING_MODE_REQUEST_INDEX 0 353#define BCM5974_WELLSPRING_MODE_REQUEST_INDEX 0
286#define ATP_WELLSPRING_MODE_VENDOR_VALUE_1 0x01 354#define BCM5974_WELLSPRING_MODE_VENDOR_VALUE 0x01
287#define ATP_WELLSPRING_MODE_VENDOR_VALUE_2 0x05 355#define BCM5974_WELLSPRING_MODE_NORMAL_VALUE 0x08
288 356
289static int atp_wellspring_init(struct atp *dev) 357static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on)
290{ 358{
291 char *data = kmalloc(8, GFP_KERNEL); 359 char *data = kmalloc(8, GFP_KERNEL);
292 int error = 0, size; 360 int retval = 0, size;
293 361
294 if (!data) { 362 if (!data) {
295 err("bcm5974: out of memory"); 363 err("bcm5974: out of memory");
296 error = -ENOMEM; 364 retval = -ENOMEM;
297 goto error; 365 goto out;
298 }
299
300 /* reset button endpoint */
301 if (usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
302 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
303 0, dev->cfg.bt_ep, NULL, 0, 5000)) {
304 err("bcm5974: could not reset button endpoint");
305 error = -EIO;
306 goto error;
307 }
308
309 /* reset trackpad endpoint */
310 if (usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
311 USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT,
312 0, dev->cfg.tp_ep, NULL, 0, 5000)) {
313 err("bcm5974: could not reset trackpad endpoint");
314 error = -EIO;
315 goto error;
316 } 366 }
317 367
318 /* read configuration */ 368 /* read configuration */
319 size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), 369 size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
320 ATP_WELLSPRING_MODE_READ_REQUEST_ID, 370 BCM5974_WELLSPRING_MODE_READ_REQUEST_ID,
321 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 371 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
322 ATP_WELLSPRING_MODE_REQUEST_VALUE, 372 BCM5974_WELLSPRING_MODE_REQUEST_VALUE,
323 ATP_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000); 373 BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000);
324 374
325 if (size != 8) { 375 if (size != 8) {
326 err("bcm5974: could not read from device"); 376 err("bcm5974: could not read from device");
327 error = -EIO; 377 retval = -EIO;
328 goto error; 378 goto out;
329 } 379 }
330 380
331 /* apply the mode switch */ 381 /* apply the mode switch */
332 data[0] = ATP_WELLSPRING_MODE_VENDOR_VALUE_1; 382 data[0] = on ?
333 data[1] = ATP_WELLSPRING_MODE_VENDOR_VALUE_2; 383 BCM5974_WELLSPRING_MODE_VENDOR_VALUE :
384 BCM5974_WELLSPRING_MODE_NORMAL_VALUE;
334 385
335 /* write configuration */ 386 /* write configuration */
336 size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), 387 size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
337 ATP_WELLSPRING_MODE_WRITE_REQUEST_ID, 388 BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID,
338 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 389 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
339 ATP_WELLSPRING_MODE_REQUEST_VALUE, 390 BCM5974_WELLSPRING_MODE_REQUEST_VALUE,
340 ATP_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000); 391 BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000);
341 392
342 if (size != 8) { 393 if (size != 8) {
343 err("bcm5974: could not write to device"); 394 err("bcm5974: could not write to device");
344 error = -EIO; 395 retval = -EIO;
345 goto error; 396 goto out;
346 } 397 }
347 398
348 dev->tp_valid = 0; 399 dprintk(2, "bcm5974: switched to %s mode.\n",
349 400 on ? "wellspring" : "normal");
350 printk(KERN_INFO "bcm5974: Wellspring mode initialized.\n");
351 401
402 out:
352 kfree(data); 403 kfree(data);
353 return 0; 404 return retval;
354
355error:
356 kfree(data);
357 return error;
358} 405}
359 406
360static void irq_button(struct urb *urb) 407static void bcm5974_irq_button(struct urb *urb)
361{ 408{
362 struct atp *dev = urb->context; 409 struct bcm5974 *dev = urb->context;
363 int error; 410 int error;
364 411
365 switch (urb->status) { 412 switch (urb->status) {
@@ -376,17 +423,9 @@ static void irq_button(struct urb *urb)
376 goto exit; 423 goto exit;
377 } 424 }
378 425
379 if (compute_bt_state(dev, dev->bt_urb->actual_length)) { 426 if (report_bt_state(dev, dev->bt_urb->actual_length))
380 dprintk(1, "bcm5974: bad button package, length: %d)\n", 427 dprintk(1, "bcm5974: bad button package, length: %d\n",
381 dev->bt_urb->actual_length); 428 dev->bt_urb->actual_length);
382 goto exit;
383 }
384
385 /* only report button state changes */
386 if (dev->bt_state != dev->bt_prev_state) {
387 input_report_key(dev->input, BTN_LEFT, dev->bt_data->button);
388 input_sync(dev->input);
389 }
390 429
391exit: 430exit:
392 error = usb_submit_urb(dev->bt_urb, GFP_ATOMIC); 431 error = usb_submit_urb(dev->bt_urb, GFP_ATOMIC);
@@ -394,10 +433,9 @@ exit:
394 err("bcm5974: button urb failed: %d", error); 433 err("bcm5974: button urb failed: %d", error);
395} 434}
396 435
397static void irq_trackpad(struct urb *urb) 436static void bcm5974_irq_trackpad(struct urb *urb)
398{ 437{
399 struct atp *dev = urb->context; 438 struct bcm5974 *dev = urb->context;
400 struct tp_state *state = &dev->tp_state;
401 int error; 439 int error;
402 440
403 switch (urb->status) { 441 switch (urb->status) {
@@ -414,26 +452,13 @@ static void irq_trackpad(struct urb *urb)
414 goto exit; 452 goto exit;
415 } 453 }
416 454
417 /* first sample data ignored */ 455 /* control response ignored */
418 if (!dev->tp_valid) { 456 if (dev->tp_urb->actual_length == 2)
419 dev->tp_valid = 1;
420 goto exit; 457 goto exit;
421 }
422 458
423 if (compute_tp_state(dev, dev->tp_urb->actual_length)) { 459 if (report_tp_state(dev, dev->tp_urb->actual_length))
424 dprintk(1, "bcm5974: bad trackpad package, length: %d)\n", 460 dprintk(1, "bcm5974: bad trackpad package, length: %d\n",
425 dev->tp_urb->actual_length); 461 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 462
438exit: 463exit:
439 error = usb_submit_urb(dev->tp_urb, GFP_ATOMIC); 464 error = usb_submit_urb(dev->tp_urb, GFP_ATOMIC);
@@ -441,107 +466,184 @@ exit:
441 err("bcm5974: trackpad urb failed: %d", error); 466 err("bcm5974: trackpad urb failed: %d", error);
442} 467}
443 468
444static int atp_open(struct input_dev *input) 469/*
470 * The Wellspring trackpad, like many recent Apple trackpads, share
471 * the usb device with the keyboard. Since keyboards are usually
472 * handled by the HID system, the device ends up being handled by two
473 * modules. Setting up the device therefore becomes slightly
474 * complicated. To enable multitouch features, a mode switch is
475 * required, which is usually applied via the control interface of the
476 * device. It can be argued where this switch should take place. In
477 * some drivers, like appletouch, the switch is made during
478 * probe. However, the hid module may also alter the state of the
479 * device, resulting in trackpad malfunction under certain
480 * circumstances. To get around this problem, there is at least one
481 * example that utilizes the USB_QUIRK_RESET_RESUME quirk in order to
482 * recieve a reset_resume request rather than the normal resume.
483 * Since the implementation of reset_resume is equal to mode switch
484 * plus start_traffic, it seems easier to always do the switch when
485 * starting traffic on the device.
486 */
487static int bcm5974_start_traffic(struct bcm5974 *dev)
445{ 488{
446 struct atp *dev = input_get_drvdata(input); 489 if (bcm5974_wellspring_mode(dev, true)) {
447 490 dprintk(1, "bcm5974: mode switch failed\n");
448 if (!dev->open) { 491 goto error;
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 } 492 }
454 493
455 dev->open = 1; 494 if (usb_submit_urb(dev->bt_urb, GFP_KERNEL))
456 dev->suspended = 0; 495 goto error;
496
497 if (usb_submit_urb(dev->tp_urb, GFP_KERNEL))
498 goto err_kill_bt;
499
457 return 0; 500 return 0;
458 501
459err_free_bt_urb: 502err_kill_bt:
460 usb_free_urb(dev->bt_urb); 503 usb_kill_urb(dev->bt_urb);
461error: 504error:
462 return -EIO; 505 return -EIO;
463} 506}
464 507
465static void atp_close(struct input_dev *input) 508static void bcm5974_pause_traffic(struct bcm5974 *dev)
466{ 509{
467 struct atp *dev = input_get_drvdata(input);
468
469 usb_kill_urb(dev->tp_urb); 510 usb_kill_urb(dev->tp_urb);
470 usb_kill_urb(dev->bt_urb); 511 usb_kill_urb(dev->bt_urb);
512 bcm5974_wellspring_mode(dev, false);
513}
514
515/*
516 * The code below implements open/close and manual suspend/resume.
517 * All functions may be called in random order.
518 *
519 * Opening a suspended device fails with EACCES - permission denied.
520 *
521 * Failing a resume leaves the device resumed but closed.
522 */
523static int bcm5974_open(struct input_dev *input)
524{
525 struct bcm5974 *dev = input_get_drvdata(input);
526 int error;
527
528 error = usb_autopm_get_interface(dev->intf);
529 if (error)
530 return error;
471 531
472 dev->open = 0; 532 mutex_lock(&dev->pm_mutex);
473 dev->suspended = 0; 533
534 error = bcm5974_start_traffic(dev);
535 if (!error)
536 dev->opened = 1;
537
538 mutex_unlock(&dev->pm_mutex);
539
540 if (error)
541 usb_autopm_put_interface(dev->intf);
542
543 return error;
544}
545
546static void bcm5974_close(struct input_dev *input)
547{
548 struct bcm5974 *dev = input_get_drvdata(input);
549
550 mutex_lock(&dev->pm_mutex);
551
552 bcm5974_pause_traffic(dev);
553 dev->opened = 0;
554
555 mutex_unlock(&dev->pm_mutex);
556
557 usb_autopm_put_interface(dev->intf);
474} 558}
475 559
476static int atp_probe(struct usb_interface *iface, 560static int bcm5974_suspend(struct usb_interface *iface, pm_message_t message)
477 const struct usb_device_id *id) 561{
562 struct bcm5974 *dev = usb_get_intfdata(iface);
563
564 mutex_lock(&dev->pm_mutex);
565
566 if (dev->opened)
567 bcm5974_pause_traffic(dev);
568
569 mutex_unlock(&dev->pm_mutex);
570
571 return 0;
572}
573
574static int bcm5974_resume(struct usb_interface *iface)
575{
576 struct bcm5974 *dev = usb_get_intfdata(iface);
577 int error = 0;
578
579 mutex_lock(&dev->pm_mutex);
580
581 if (dev->opened)
582 error = bcm5974_start_traffic(dev);
583
584 mutex_unlock(&dev->pm_mutex);
585
586 return error;
587}
588
589static int bcm5974_probe(struct usb_interface *iface,
590 const struct usb_device_id *id)
478{ 591{
479 struct usb_device *udev = interface_to_usbdev(iface); 592 struct usb_device *udev = interface_to_usbdev(iface);
480 const struct atp_config *cfg; 593 const struct bcm5974_config *cfg;
481 struct atp *dev; 594 struct bcm5974 *dev;
482 struct input_dev *input_dev; 595 struct input_dev *input_dev;
483 int error = 0; 596 int error = -ENOMEM;
484 597
485 /* find the product index */ 598 /* find the product index */
486 cfg = atp_product_config(udev); 599 cfg = bcm5974_get_config(udev);
487 600
488 /* allocate memory for our device state and initialize it */ 601 /* allocate memory for our device state and initialize it */
489 dev = kzalloc(sizeof(struct atp), GFP_KERNEL); 602 dev = kzalloc(sizeof(struct bcm5974), GFP_KERNEL);
490 input_dev = input_allocate_device(); 603 input_dev = input_allocate_device();
491 if (!dev || !input_dev) { 604 if (!dev || !input_dev) {
492 err("bcm5974: out of memory"); 605 err("bcm5974: out of memory");
493 error = -ENOMEM;
494 goto err_free_devs; 606 goto err_free_devs;
495 } 607 }
496 608
497 dev->udev = udev; 609 dev->udev = udev;
610 dev->intf = iface;
498 dev->input = input_dev; 611 dev->input = input_dev;
499 dev->cfg = *cfg; 612 dev->cfg = *cfg;
613 mutex_init(&dev->pm_mutex);
500 614
501 /* switch to raw sensor mode */ 615 /* setup urbs */
502 if (atp_wellspring_init(dev)) {
503 error = -EIO;
504 goto err_free_devs;
505 }
506
507 dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL); 616 dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL);
508 if (!dev->bt_urb) { 617 if (!dev->bt_urb)
509 error = -ENOMEM;
510 goto err_free_devs; 618 goto err_free_devs;
511 }
512 619
513 dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL); 620 dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL);
514 if (!dev->tp_urb) { 621 if (!dev->tp_urb)
515 error = -ENOMEM;
516 goto err_free_bt_urb; 622 goto err_free_bt_urb;
517 }
518 623
519 dev->bt_data = usb_buffer_alloc(dev->udev, 624 dev->bt_data = usb_buffer_alloc(dev->udev,
520 dev->cfg.bt_datalen, GFP_KERNEL, 625 dev->cfg.bt_datalen, GFP_KERNEL,
521 &dev->bt_urb->transfer_dma); 626 &dev->bt_urb->transfer_dma);
522 if (!dev->bt_data) { 627 if (!dev->bt_data)
523 error = -ENOMEM;
524 goto err_free_urb; 628 goto err_free_urb;
525 }
526 629
527 dev->tp_data = usb_buffer_alloc(dev->udev, 630 dev->tp_data = usb_buffer_alloc(dev->udev,
528 dev->cfg.tp_datalen, GFP_KERNEL, 631 dev->cfg.tp_datalen, GFP_KERNEL,
529 &dev->tp_urb->transfer_dma); 632 &dev->tp_urb->transfer_dma);
530 if (!dev->tp_data) { 633 if (!dev->tp_data)
531 error = -ENOMEM;
532 goto err_free_bt_buffer; 634 goto err_free_bt_buffer;
533 }
534 635
535 usb_fill_int_urb(dev->bt_urb, udev, 636 usb_fill_int_urb(dev->bt_urb, udev,
536 usb_rcvintpipe(udev, cfg->bt_ep), 637 usb_rcvintpipe(udev, cfg->bt_ep),
537 dev->bt_data, dev->cfg.bt_datalen, 638 dev->bt_data, dev->cfg.bt_datalen,
538 irq_button, dev, 1); 639 bcm5974_irq_button, dev, 1);
539 640
540 usb_fill_int_urb(dev->tp_urb, udev, 641 usb_fill_int_urb(dev->tp_urb, udev,
541 usb_rcvintpipe(udev, cfg->tp_ep), 642 usb_rcvintpipe(udev, cfg->tp_ep),
542 dev->tp_data, dev->cfg.tp_datalen, 643 dev->tp_data, dev->cfg.tp_datalen,
543 irq_trackpad, dev, 1); 644 bcm5974_irq_trackpad, dev, 1);
544 645
646 /* create bcm5974 device */
545 usb_make_path(udev, dev->phys, sizeof(dev->phys)); 647 usb_make_path(udev, dev->phys, sizeof(dev->phys));
546 strlcat(dev->phys, "/input0", sizeof(dev->phys)); 648 strlcat(dev->phys, "/input0", sizeof(dev->phys));
547 649
@@ -552,24 +654,10 @@ static int atp_probe(struct usb_interface *iface,
552 654
553 input_set_drvdata(input_dev, dev); 655 input_set_drvdata(input_dev, dev);
554 656
555 input_dev->open = atp_open; 657 input_dev->open = bcm5974_open;
556 input_dev->close = atp_close; 658 input_dev->close = bcm5974_close;
557
558 set_bit(EV_ABS, input_dev->evbit);
559 input_set_abs_params(input_dev, ABS_PRESSURE,
560 0, cfg->p.dim, cfg->p.dim / SNRATIO, 0);
561 input_set_abs_params(input_dev, ABS_TOOL_WIDTH,
562 0, cfg->w.dim, cfg->w.dim / SNRATIO, 0);
563 input_set_abs_params(input_dev, ABS_X,
564 0, cfg->x.dim, cfg->x.dim / SNRATIO, 0);
565 input_set_abs_params(input_dev, ABS_Y,
566 0, cfg->y.dim, cfg->y.dim / SNRATIO, 0);
567 659
568 set_bit(EV_KEY, input_dev->evbit); 660 setup_events_to_report(input_dev, cfg);
569 set_bit(BTN_TOOL_FINGER, input_dev->keybit);
570 set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
571 set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
572 set_bit(BTN_LEFT, input_dev->keybit);
573 661
574 error = input_register_device(dev->input); 662 error = input_register_device(dev->input);
575 if (error) 663 if (error)
@@ -592,99 +680,48 @@ err_free_bt_urb:
592 usb_free_urb(dev->bt_urb); 680 usb_free_urb(dev->bt_urb);
593err_free_devs: 681err_free_devs:
594 usb_set_intfdata(iface, NULL); 682 usb_set_intfdata(iface, NULL);
595 kfree(dev);
596 input_free_device(input_dev); 683 input_free_device(input_dev);
684 kfree(dev);
597 return error; 685 return error;
598} 686}
599 687
600static void atp_disconnect(struct usb_interface *iface) 688static void bcm5974_disconnect(struct usb_interface *iface)
601{ 689{
602 struct atp *dev = usb_get_intfdata(iface); 690 struct bcm5974 *dev = usb_get_intfdata(iface);
603 691
604 usb_set_intfdata(iface, NULL); 692 usb_set_intfdata(iface, NULL);
605 693
606 if (dev) { 694 input_unregister_device(dev->input);
607 input_unregister_device(dev->input); 695 usb_buffer_free(dev->udev, dev->cfg.tp_datalen,
608 usb_buffer_free(dev->udev, dev->cfg.tp_datalen,
609 dev->tp_data, dev->tp_urb->transfer_dma); 696 dev->tp_data, dev->tp_urb->transfer_dma);
610 usb_buffer_free(dev->udev, dev->cfg.bt_datalen, 697 usb_buffer_free(dev->udev, dev->cfg.bt_datalen,
611 dev->bt_data, dev->bt_urb->transfer_dma); 698 dev->bt_data, dev->bt_urb->transfer_dma);
612 usb_free_urb(dev->tp_urb); 699 usb_free_urb(dev->tp_urb);
613 usb_free_urb(dev->bt_urb); 700 usb_free_urb(dev->bt_urb);
614 kfree(dev); 701 kfree(dev);
615 }
616
617 printk(KERN_INFO "bcm5974: disconnected\n");
618}
619
620static int atp_suspend(struct usb_interface *iface, pm_message_t message)
621{
622 struct atp *dev = usb_get_intfdata(iface);
623
624 if (dev) {
625 if (!dev->suspended)
626 atp_close(dev->input);
627 dev->suspended++;
628 }
629
630 return 0;
631}
632
633static int atp_resume(struct usb_interface *iface)
634{
635 struct atp *dev = usb_get_intfdata(iface);
636 int error = 0;
637
638 if (dev && dev->suspended) {
639 if (!--dev->suspended)
640 error = atp_open(dev->input);
641 }
642
643 return error;
644}
645
646static int atp_reset_resume(struct usb_interface *iface)
647{
648 struct atp *dev = usb_get_intfdata(iface);
649
650 if (dev && atp_wellspring_init(dev))
651 printk(KERN_INFO "bcm5974: warning: reset failed\n");
652
653 return atp_resume(iface);
654}
655
656static int atp_pre_reset(struct usb_interface *iface)
657{
658 return atp_suspend(iface, PMSG_ON);
659}
660
661static int atp_post_reset(struct usb_interface *iface)
662{
663 return atp_reset_resume(iface);
664} 702}
665 703
666static struct usb_driver atp_driver = { 704static struct usb_driver bcm5974_driver = {
667 .name = "bcm5974", 705 .name = "bcm5974",
668 .probe = atp_probe, 706 .probe = bcm5974_probe,
669 .disconnect = atp_disconnect, 707 .disconnect = bcm5974_disconnect,
670 .suspend = atp_suspend, 708 .suspend = bcm5974_suspend,
671 .resume = atp_resume, 709 .resume = bcm5974_resume,
672 .reset_resume = atp_reset_resume, 710 .reset_resume = bcm5974_resume,
673 .pre_reset = atp_pre_reset, 711 .id_table = bcm5974_table,
674 .post_reset = atp_post_reset, 712 .supports_autosuspend = 1,
675 .id_table = atp_table,
676}; 713};
677 714
678static int __init atp_init(void) 715static int __init bcm5974_init(void)
679{ 716{
680 return usb_register(&atp_driver); 717 return usb_register(&bcm5974_driver);
681} 718}
682 719
683static void __exit atp_exit(void) 720static void __exit bcm5974_exit(void)
684{ 721{
685 usb_deregister(&atp_driver); 722 usb_deregister(&bcm5974_driver);
686} 723}
687 724
688module_init(atp_init); 725module_init(bcm5974_init);
689module_exit(atp_exit); 726module_exit(bcm5974_exit);
690 727