aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/input/appletouch.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/input/appletouch.c')
-rw-r--r--drivers/usb/input/appletouch.c117
1 files changed, 108 insertions, 9 deletions
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c
index c222ed13deab..36855062eacc 100644
--- a/drivers/usb/input/appletouch.c
+++ b/drivers/usb/input/appletouch.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Apple USB Touchpad (for post-February 2005 PowerBooks) driver 2 * Apple USB Touchpad (for post-February 2005 PowerBooks and MacBooks) driver
3 * 3 *
4 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) 4 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
5 * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net) 5 * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net)
@@ -7,6 +7,7 @@
7 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) 7 * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
8 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) 8 * Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
9 * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch) 9 * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch)
10 * Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch)
10 * 11 *
11 * Thanks to Alex Harper <basilisk@foobox.net> for his inputs. 12 * Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
12 * 13 *
@@ -32,9 +33,7 @@
32#include <linux/init.h> 33#include <linux/init.h>
33#include <linux/slab.h> 34#include <linux/slab.h>
34#include <linux/module.h> 35#include <linux/module.h>
35#include <linux/usb.h> 36#include <linux/usb/input.h>
36#include <linux/input.h>
37#include <linux/usb_input.h>
38 37
39/* Apple has powerbooks which have the keyboard with different Product IDs */ 38/* Apple has powerbooks which have the keyboard with different Product IDs */
40#define APPLE_VENDOR_ID 0x05AC 39#define APPLE_VENDOR_ID 0x05AC
@@ -44,6 +43,11 @@
44#define GEYSER_ISO_PRODUCT_ID 0x0215 43#define GEYSER_ISO_PRODUCT_ID 0x0215
45#define GEYSER_JIS_PRODUCT_ID 0x0216 44#define GEYSER_JIS_PRODUCT_ID 0x0216
46 45
46/* MacBook devices */
47#define GEYSER3_ANSI_PRODUCT_ID 0x0217
48#define GEYSER3_ISO_PRODUCT_ID 0x0218
49#define GEYSER3_JIS_PRODUCT_ID 0x0219
50
47#define ATP_DEVICE(prod) \ 51#define ATP_DEVICE(prod) \
48 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ 52 .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
49 USB_DEVICE_ID_MATCH_INT_CLASS | \ 53 USB_DEVICE_ID_MATCH_INT_CLASS | \
@@ -65,6 +69,10 @@ static struct usb_device_id atp_table [] = {
65 { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) }, 69 { ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) },
66 { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) }, 70 { ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) },
67 71
72 { ATP_DEVICE(GEYSER3_ANSI_PRODUCT_ID) },
73 { ATP_DEVICE(GEYSER3_ISO_PRODUCT_ID) },
74 { ATP_DEVICE(GEYSER3_JIS_PRODUCT_ID) },
75
68 /* Terminating entry */ 76 /* Terminating entry */
69 { } 77 { }
70}; 78};
@@ -101,6 +109,13 @@ MODULE_DEVICE_TABLE (usb, atp_table);
101 */ 109 */
102#define ATP_THRESHOLD 5 110#define ATP_THRESHOLD 5
103 111
112/* MacBook Pro (Geyser 3) initialization constants */
113#define ATP_GEYSER3_MODE_READ_REQUEST_ID 1
114#define ATP_GEYSER3_MODE_WRITE_REQUEST_ID 9
115#define ATP_GEYSER3_MODE_REQUEST_VALUE 0x300
116#define ATP_GEYSER3_MODE_REQUEST_INDEX 0
117#define ATP_GEYSER3_MODE_VENDOR_VALUE 0x04
118
104/* Structure to hold all of our device specific stuff */ 119/* Structure to hold all of our device specific stuff */
105struct atp { 120struct atp {
106 char phys[64]; 121 char phys[64];
@@ -147,13 +162,22 @@ MODULE_PARM_DESC(debug, "Activate debugging output");
147/* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */ 162/* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */
148static inline int atp_is_geyser_2(struct atp *dev) 163static inline int atp_is_geyser_2(struct atp *dev)
149{ 164{
150 int16_t productId = le16_to_cpu(dev->udev->descriptor.idProduct); 165 u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
151 166
152 return (productId == GEYSER_ANSI_PRODUCT_ID) || 167 return (productId == GEYSER_ANSI_PRODUCT_ID) ||
153 (productId == GEYSER_ISO_PRODUCT_ID) || 168 (productId == GEYSER_ISO_PRODUCT_ID) ||
154 (productId == GEYSER_JIS_PRODUCT_ID); 169 (productId == GEYSER_JIS_PRODUCT_ID);
155} 170}
156 171
172static inline int atp_is_geyser_3(struct atp *dev)
173{
174 u16 productId = le16_to_cpu(dev->udev->descriptor.idProduct);
175
176 return (productId == GEYSER3_ANSI_PRODUCT_ID) ||
177 (productId == GEYSER3_ISO_PRODUCT_ID) ||
178 (productId == GEYSER3_JIS_PRODUCT_ID);
179}
180
157static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, 181static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
158 int *z, int *fingers) 182 int *z, int *fingers)
159{ 183{
@@ -219,12 +243,33 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
219 243
220 /* drop incomplete datasets */ 244 /* drop incomplete datasets */
221 if (dev->urb->actual_length != dev->datalen) { 245 if (dev->urb->actual_length != dev->datalen) {
222 dprintk("appletouch: incomplete data package.\n"); 246 dprintk("appletouch: incomplete data package"
247 " (first byte: %d, length: %d).\n",
248 dev->data[0], dev->urb->actual_length);
223 goto exit; 249 goto exit;
224 } 250 }
225 251
226 /* reorder the sensors values */ 252 /* reorder the sensors values */
227 if (atp_is_geyser_2(dev)) { 253 if (atp_is_geyser_3(dev)) {
254 memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
255
256 /*
257 * The values are laid out like this:
258 * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ...
259 * '-' is an unused value.
260 */
261
262 /* read X values */
263 for (i = 0, j = 19; i < 20; i += 2, j += 3) {
264 dev->xy_cur[i] = dev->data[j + 1];
265 dev->xy_cur[i + 1] = dev->data[j + 2];
266 }
267 /* read Y values */
268 for (i = 0, j = 1; i < 9; i += 2, j += 3) {
269 dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];
270 dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];
271 }
272 } else if (atp_is_geyser_2(dev)) {
228 memset(dev->xy_cur, 0, sizeof(dev->xy_cur)); 273 memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
229 274
230 /* 275 /*
@@ -267,6 +312,9 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
267 dev->x_old = dev->y_old = -1; 312 dev->x_old = dev->y_old = -1;
268 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old)); 313 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
269 314
315 if (atp_is_geyser_3(dev)) /* No 17" Macbooks (yet) */
316 goto exit;
317
270 /* 17" Powerbooks have extra X sensors */ 318 /* 17" Powerbooks have extra X sensors */
271 for (i = (atp_is_geyser_2(dev)?15:16); i < ATP_XSENSORS; i++) { 319 for (i = (atp_is_geyser_2(dev)?15:16); i < ATP_XSENSORS; i++) {
272 if (!dev->xy_cur[i]) continue; 320 if (!dev->xy_cur[i]) continue;
@@ -414,7 +462,50 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
414 dev->udev = udev; 462 dev->udev = udev;
415 dev->input = input_dev; 463 dev->input = input_dev;
416 dev->overflowwarn = 0; 464 dev->overflowwarn = 0;
417 dev->datalen = (atp_is_geyser_2(dev)?64:81); 465 if (atp_is_geyser_3(dev))
466 dev->datalen = 64;
467 else if (atp_is_geyser_2(dev))
468 dev->datalen = 64;
469 else
470 dev->datalen = 81;
471
472 if (atp_is_geyser_3(dev)) {
473 /*
474 * By default Geyser 3 device sends standard USB HID mouse
475 * packets (Report ID 2). This code changes device mode, so it
476 * sends raw sensor reports (Report ID 5).
477 */
478 char data[8];
479 int size;
480
481 size = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
482 ATP_GEYSER3_MODE_READ_REQUEST_ID,
483 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
484 ATP_GEYSER3_MODE_REQUEST_VALUE,
485 ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);
486
487 if (size != 8) {
488 err("Could not do mode read request from device"
489 " (Geyser 3 mode)");
490 goto err_free_devs;
491 }
492
493 /* Apply the mode switch */
494 data[0] = ATP_GEYSER3_MODE_VENDOR_VALUE;
495
496 size = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
497 ATP_GEYSER3_MODE_WRITE_REQUEST_ID,
498 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
499 ATP_GEYSER3_MODE_REQUEST_VALUE,
500 ATP_GEYSER3_MODE_REQUEST_INDEX, &data, 8, 5000);
501
502 if (size != 8) {
503 err("Could not do mode write request to device"
504 " (Geyser 3 mode)");
505 goto err_free_devs;
506 }
507 printk("appletouch Geyser 3 inited.\n");
508 }
418 509
419 dev->urb = usb_alloc_urb(0, GFP_KERNEL); 510 dev->urb = usb_alloc_urb(0, GFP_KERNEL);
420 if (!dev->urb) { 511 if (!dev->urb) {
@@ -447,7 +538,15 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
447 538
448 set_bit(EV_ABS, input_dev->evbit); 539 set_bit(EV_ABS, input_dev->evbit);
449 540
450 if (atp_is_geyser_2(dev)) { 541 if (atp_is_geyser_3(dev)) {
542 /*
543 * MacBook have 20 X sensors, 10 Y sensors
544 */
545 input_set_abs_params(input_dev, ABS_X, 0,
546 ((20 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0);
547 input_set_abs_params(input_dev, ABS_Y, 0,
548 ((10 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0);
549 } else if (atp_is_geyser_2(dev)) {
451 /* 550 /*
452 * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected 551 * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected
453 * later. 552 * later.