Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S263355AbTF0CZE (ORCPT ); Thu, 26 Jun 2003 22:25:04 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S263365AbTF0CZD (ORCPT ); Thu, 26 Jun 2003 22:25:03 -0400 Received: from tone.orchestra.cse.unsw.EDU.AU ([129.94.242.28]:52184 "HELO tone.orchestra.cse.unsw.EDU.AU") by vger.kernel.org with SMTP id S263355AbTF0CYz (ORCPT ); Thu, 26 Jun 2003 22:24:55 -0400 From: Neil Brown To: Vojtech Pavlik Date: Fri, 27 Jun 2003 12:38:50 +1000 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <16123.44602.150927.280989@gargle.gargle.HOWL> Cc: linux-kernel@vger.kernel.org Subject: PATCH - ALPS glidepoint/dualpoint driver for 2.5.7x X-Mailer: VM 7.16 under Emacs 21.3.2 X-face: [Gw_3E*Gng}4rRrKRYotwlE?.2|**#s9Dpacket; + struct input_dev *dev = &psmouse->dev; + int x,y,z; + + input_regs(dev, regs); + + x = (packet[1] & 0x7f) | ((packet[2] & 0x78)<<(7-3)); + y = (packet[4] & 0x7f) | ((packet[3] & 0x70)<<(7-4)); + z = packet[5]; + + if (z > 0) { + input_report_abs(dev, ABS_X, x); + input_report_abs(dev, ABS_Y, y); + input_report_abs(dev, ABS_PRESSURE, z); + } else + input_report_abs(dev, ABS_PRESSURE, 0); + + input_report_key(dev, BTN_LEFT, ((packet[0] | packet[3]) ) & 1); + input_report_key(dev, BTN_MIDDLE, ((packet[0] | packet[3]) >> 2) & 1); + input_report_key(dev, BTN_RIGHT, ((packet[0] | packet[3]) >> 1) & 1); + + input_report_key(dev, BTN_TOUCH, packet[2] & 1); + + input_sync(dev); +} + +/* * psmouse_interrupt() handles incoming characters, either gathering them into * packets or passing them to the command routine as command output. */ @@ -139,6 +181,19 @@ static irqreturn_t psmouse_interrupt(str psmouse->last = jiffies; psmouse->packet[psmouse->pktcnt++] = data; + /* ALPS absolute mode packets start with 0b11111mrl + * Normal mouse packets are extremely unlikely to overflow both + * x and y + */ + if (!psmouse_noext && psmouse->type < PSMOUSE_GENPS && + (psmouse->packet[0] & 0xf8)== 0xf8) { + if (psmouse->pktcnt == 6) { + ALPS_process_packet(psmouse, regs); + psmouse->pktcnt = 0; + } + goto out; + } + if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) { psmouse_process_packet(psmouse, regs); psmouse->pktcnt = 0; @@ -424,6 +479,17 @@ static void psmouse_set_resolution(struc * psmouse_initialize() initializes the mouse to a sane state. */ +static inline void set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat) +{ + dev->absmin[axis] = min; + dev->absmax[axis] = max; + dev->absfuzz[axis] = fuzz; + dev->absflat[axis] = flat; + + set_bit(axis, dev->absbit); +} + + static void psmouse_initialize(struct psmouse *psmouse) { unsigned char param[2]; @@ -453,8 +519,23 @@ static void psmouse_initialize(struct ps /* * Last, we enable the mouse so that we get reports from it. - */ + * If it is a 3-byte setting and we are allowed to use extensions, + * then it could be an ALPS Glidepoint, so send the init sequence just + * incase. i.e. 4 consecutive "disable"s before the "enable" + */ + if (psmouse->type < PSMOUSE_GENPS && !psmouse_noext) { + psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE); + psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE); + psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE); + psmouse_command(psmouse, NULL, PSMOUSE_CMD_DISABLE); + + set_bit(BTN_TOUCH, psmouse->dev.keybit); + set_bit(EV_ABS, psmouse->dev.evbit); + set_abs_params(&psmouse->dev, ABS_X, 0, 0, 0, 0); + set_abs_params(&psmouse->dev, ABS_Y, 0, 0, 0, 0); + set_abs_params(&psmouse->dev, ABS_PRESSURE, 0, 127, 0, 0); + } if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_ENABLE)) printk(KERN_WARNING "psmouse.c: Failed to enable mouse on %s\n", psmouse->serio->phys); diff ./drivers/input/mouse/psmouse.h~current~ ./drivers/input/mouse/psmouse.h --- ./drivers/input/mouse/psmouse.h~current~ 2003-06-26 13:49:26.000000000 +1000 +++ ./drivers/input/mouse/psmouse.h 2003-06-26 13:50:16.000000000 +1000 @@ -9,6 +9,7 @@ #define PSMOUSE_CMD_GETID 0x02f2 #define PSMOUSE_CMD_SETRATE 0x10f3 #define PSMOUSE_CMD_ENABLE 0x00f4 +#define PSMOUSE_CMD_DISABLE 0x00f5 #define PSMOUSE_CMD_RESET_DIS 0x00f6 #define PSMOUSE_CMD_RESET_BAT 0x02ff diff ./drivers/input/mousedev.c~current~ ./drivers/input/mousedev.c --- ./drivers/input/mousedev.c~current~ 2003-06-26 13:49:26.000000000 +1000 +++ ./drivers/input/mousedev.c 2003-06-26 13:50:22.000000000 +1000 @@ -53,7 +53,7 @@ struct mousedev_list { struct fasync_struct *fasync; struct mousedev *mousedev; struct list_head node; - int dx, dy, dz, oldx, oldy; + int dx, dy, dz, oldx, oldy, finger; signed char ps2[6]; unsigned long buttons; unsigned char ready, buffer, bufsiz; @@ -79,6 +79,7 @@ static void mousedev_event(struct input_ struct mousedev **mousedev = mousedevs; struct mousedev_list *list; int index, size, wake; + int dx, dy; while (*mousedev) { @@ -93,23 +94,30 @@ static void mousedev_event(struct input_ case ABS_X: size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X]; if (size != 0) { - list->dx += (value * xres - list->oldx) / size; - list->oldx += list->dx * size; + dx = list->dx + (value * xres - list->oldx) / size; + list->oldx += dx * size; } else { - list->dx += value - list->oldx; - list->oldx += list->dx; + dx = list->dx + value - list->oldx; + list->oldx += dx; } + if (list->finger || !test_bit(ABS_PRESSURE, handle->dev->absbit)) + list->dx = dx; break; case ABS_Y: size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y]; if (size != 0) { - list->dy -= (value * yres - list->oldy) / size; - list->oldy -= list->dy * size; + dy = list->dy - (value * yres - list->oldy) / size; + list->oldy -= dy * size; } else { - list->dy -= value - list->oldy; - list->oldy -= list->dy; + dy = list->dy - (value - list->oldy); + list->oldy -= dy; } + if (list->finger || !test_bit(ABS_PRESSURE, handle->dev->absbit)) + list->dy = dy; + break; + case ABS_PRESSURE: + list->finger = value; break; } break; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/