aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/appletouch.c
diff options
context:
space:
mode:
authorSven Anders <anders@anduras.de>2008-08-08 16:31:33 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2008-08-08 16:44:28 -0400
commit82a196f481661170b4982dc7e68a12e9253309d0 (patch)
tree26b047fe68743247162b4b0401ab8740960328be /drivers/input/mouse/appletouch.c
parentd83d213d9fda671dfd84ea81182742f9e329a6b4 (diff)
Input: appletouch - handle geyser 3/4 status bits
Implement support for status bits on Geyser 3/4. Signed-off-by: Sven Anders <anders@anduras.de> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/mouse/appletouch.c')
-rw-r--r--drivers/input/mouse/appletouch.c53
1 files changed, 35 insertions, 18 deletions
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index 36ebe5c25ee3..079816e6b23b 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -136,12 +136,28 @@ MODULE_DEVICE_TABLE(usb, atp_table);
136#define ATP_GEYSER_MODE_REQUEST_INDEX 0 136#define ATP_GEYSER_MODE_REQUEST_INDEX 0
137#define ATP_GEYSER_MODE_VENDOR_VALUE 0x04 137#define ATP_GEYSER_MODE_VENDOR_VALUE 0x04
138 138
139/**
140 * enum atp_status_bits - status bit meanings
141 *
142 * These constants represent the meaning of the status bits.
143 * (only Geyser 3/4)
144 *
145 * @ATP_STATUS_BUTTON: The button was pressed
146 * @ATP_STATUS_BASE_UPDATE: Update of the base values (untouched pad)
147 * @ATP_STATUS_FROM_RESET: Reset previously performed
148 */
149enum atp_status_bits {
150 ATP_STATUS_BUTTON = BIT(0),
151 ATP_STATUS_BASE_UPDATE = BIT(2),
152 ATP_STATUS_FROM_RESET = BIT(4),
153};
154
139/* Structure to hold all of our device specific stuff */ 155/* Structure to hold all of our device specific stuff */
140struct atp { 156struct atp {
141 char phys[64]; 157 char phys[64];
142 struct usb_device *udev; /* usb device */ 158 struct usb_device *udev; /* usb device */
143 struct urb *urb; /* usb request block */ 159 struct urb *urb; /* usb request block */
144 signed char *data; /* transferred data */ 160 u8 *data; /* transferred data */
145 struct input_dev *input; /* input dev */ 161 struct input_dev *input; /* input dev */
146 enum atp_touchpad_type type; /* type of touchpad */ 162 enum atp_touchpad_type type; /* type of touchpad */
147 bool open; 163 bool open;
@@ -251,8 +267,6 @@ static void atp_reinit(struct work_struct *work)
251 int retval; 267 int retval;
252 268
253 dprintk("appletouch: putting appletouch to sleep (reinit)\n"); 269 dprintk("appletouch: putting appletouch to sleep (reinit)\n");
254 dev->idlecount = 0;
255
256 atp_geyser_init(udev); 270 atp_geyser_init(udev);
257 271
258 retval = usb_submit_urb(dev->urb, GFP_ATOMIC); 272 retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
@@ -488,7 +502,7 @@ static void atp_complete_geyser_1_2(struct urb *urb)
488 ATP_XFACT, &x_z, &x_f); 502 ATP_XFACT, &x_z, &x_f);
489 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS, 503 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,
490 ATP_YFACT, &y_z, &y_f); 504 ATP_YFACT, &y_z, &y_f);
491 key = dev->data[dev->datalen - 1] & 1; 505 key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON;
492 506
493 if (x && y) { 507 if (x && y) {
494 if (dev->x_old != -1) { 508 if (dev->x_old != -1) {
@@ -568,34 +582,38 @@ static void atp_complete_geyser_3_4(struct urb *urb)
568 582
569 dbg_dump("sample", dev->xy_cur); 583 dbg_dump("sample", dev->xy_cur);
570 584
571 if (!dev->valid) { 585 /* Just update the base values (i.e. touchpad in untouched state) */
572 /* first sample */ 586 if (dev->data[dev->datalen - 1] & ATP_STATUS_BASE_UPDATE) {
573 dev->valid = true;
574 dev->x_old = dev->y_old = -1;
575 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
576 587
588 dprintk(KERN_DEBUG "appletouch: updated base values\n");
589
590 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
577 goto exit; 591 goto exit;
578 } 592 }
579 593
580 for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) { 594 for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {
581 /* accumulate the change */ 595 /* calculate the change */
582 signed char change = dev->xy_old[i] - dev->xy_cur[i]; 596 dev->xy_acc[i] = dev->xy_cur[i] - dev->xy_old[i];
583 dev->xy_acc[i] -= change; 597
598 /* this is a round-robin value, so couple with that */
599 if (dev->xy_acc[i] > 127)
600 dev->xy_acc[i] -= 256;
601
602 if (dev->xy_acc[i] < -127)
603 dev->xy_acc[i] += 256;
584 604
585 /* prevent down drifting */ 605 /* prevent down drifting */
586 if (dev->xy_acc[i] < 0) 606 if (dev->xy_acc[i] < 0)
587 dev->xy_acc[i] = 0; 607 dev->xy_acc[i] = 0;
588 } 608 }
589 609
590 memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
591
592 dbg_dump("accumulator", dev->xy_acc); 610 dbg_dump("accumulator", dev->xy_acc);
593 611
594 x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS, 612 x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS,
595 ATP_XFACT, &x_z, &x_f); 613 ATP_XFACT, &x_z, &x_f);
596 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS, 614 y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,
597 ATP_YFACT, &y_z, &y_f); 615 ATP_YFACT, &y_z, &y_f);
598 key = dev->data[dev->datalen - 1] & 1; 616 key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON;
599 617
600 if (x && y) { 618 if (x && y) {
601 if (dev->x_old != -1) { 619 if (dev->x_old != -1) {
@@ -647,7 +665,8 @@ static void atp_complete_geyser_3_4(struct urb *urb)
647 if (!x && !y && !key) { 665 if (!x && !y && !key) {
648 dev->idlecount++; 666 dev->idlecount++;
649 if (dev->idlecount == 10) { 667 if (dev->idlecount == 10) {
650 dev->valid = false; 668 dev->x_old = dev->y_old = -1;
669 dev->idlecount = 0;
651 schedule_work(&dev->work); 670 schedule_work(&dev->work);
652 /* Don't resubmit urb here, wait for reinit */ 671 /* Don't resubmit urb here, wait for reinit */
653 return; 672 return;
@@ -879,8 +898,6 @@ static int atp_suspend(struct usb_interface *iface, pm_message_t message)
879 struct atp *dev = usb_get_intfdata(iface); 898 struct atp *dev = usb_get_intfdata(iface);
880 899
881 usb_kill_urb(dev->urb); 900 usb_kill_urb(dev->urb);
882 dev->valid = false;
883
884 return 0; 901 return 0;
885} 902}
886 903