Commit 1e12aaf0 authored by Vojtech Pavlik's avatar Vojtech Pavlik

Merge suse.cz:/home/vojtech/bk/linus

into suse.cz:/home/vojtech/bk/for-linus
parents 7b0f9236 56b3ffec
...@@ -896,8 +896,8 @@ running once the system is up. ...@@ -896,8 +896,8 @@ running once the system is up.
psmouse.rate= [HW,MOUSE] Set desired mouse report rate, in reports psmouse.rate= [HW,MOUSE] Set desired mouse report rate, in reports
per second. per second.
psmouse.resetafter= psmouse.resetafter=
[HW,MOUSE] Try to reset Synaptics Touchpad after so many [HW,MOUSE] Try to reset the device after so many bad packets
bad packets (0 = never). (0 = never).
psmouse.resolution= psmouse.resolution=
[HW,MOUSE] Set desired mouse resolution, in dpi. [HW,MOUSE] Set desired mouse resolution, in dpi.
psmouse.smartscroll= psmouse.smartscroll=
......
...@@ -41,9 +41,16 @@ config INPUT_MOUSEDEV ...@@ -41,9 +41,16 @@ config INPUT_MOUSEDEV
module will be called mousedev. module will be called mousedev.
config INPUT_MOUSEDEV_PSAUX config INPUT_MOUSEDEV_PSAUX
bool "Provide legacy /dev/psaux device" if EMBEDDED bool "Provide legacy /dev/psaux device"
default y default y
depends on INPUT_MOUSEDEV depends on INPUT_MOUSEDEV
---help---
Say Y here if you want your mouse also be accessible as char device
10:1 - /dev/psaux. The data available through /dev/psaux is exactly
the same as the data from /dev/input/mice.
If unsure, say Y.
config INPUT_MOUSEDEV_SCREEN_X config INPUT_MOUSEDEV_SCREEN_X
int "Horizontal screen resolution" int "Horizontal screen resolution"
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#include <linux/device.h> #include <linux/device.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Input driver event debug module"); MODULE_DESCRIPTION("Input driver event debug module");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static char evbug_name[] = "evbug"; static char evbug_name[] = "evbug";
...@@ -67,7 +67,7 @@ static struct input_handle *evbug_connect(struct input_handler *handler, struct ...@@ -67,7 +67,7 @@ static struct input_handle *evbug_connect(struct input_handler *handler, struct
static void evbug_disconnect(struct input_handle *handle) static void evbug_disconnect(struct input_handle *handle)
{ {
printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys); printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys);
input_close_device(handle); input_close_device(handle);
kfree(handle); kfree(handle);
...@@ -79,7 +79,7 @@ static struct input_device_id evbug_ids[] = { ...@@ -79,7 +79,7 @@ static struct input_device_id evbug_ids[] = {
}; };
MODULE_DEVICE_TABLE(input, evbug_ids); MODULE_DEVICE_TABLE(input, evbug_ids);
static struct input_handler evbug_handler = { static struct input_handler evbug_handler = {
.event = evbug_event, .event = evbug_event,
.connect = evbug_connect, .connect = evbug_connect,
......
...@@ -126,7 +126,7 @@ static int evdev_open(struct inode * inode, struct file * file) ...@@ -126,7 +126,7 @@ static int evdev_open(struct inode * inode, struct file * file)
int i = iminor(inode) - EVDEV_MINOR_BASE; int i = iminor(inode) - EVDEV_MINOR_BASE;
int accept_err; int accept_err;
if (i >= EVDEV_MINORS || !evdev_table[i]) if (i >= EVDEV_MINORS || !evdev_table[i] || !evdev_table[i]->exist)
return -ENODEV; return -ENODEV;
if ((accept_err = input_accept_process(&(evdev_table[i]->handle), file))) if ((accept_err = input_accept_process(&(evdev_table[i]->handle), file)))
...@@ -175,7 +175,7 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count ...@@ -175,7 +175,7 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count
return -EAGAIN; return -EAGAIN;
retval = wait_event_interruptible(list->evdev->wait, retval = wait_event_interruptible(list->evdev->wait,
list->head != list->tail && list->evdev->exist); list->head != list->tail || (!list->evdev->exist));
if (retval) if (retval)
return retval; return retval;
...@@ -222,7 +222,7 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ...@@ -222,7 +222,7 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case EVIOCGID: case EVIOCGID:
return copy_to_user(p, &dev->id, sizeof(struct input_id)) ? -EFAULT : 0; return copy_to_user(p, &dev->id, sizeof(struct input_id)) ? -EFAULT : 0;
case EVIOCGKEYCODE: case EVIOCGKEYCODE:
if (get_user(t, ip)) return -EFAULT; if (get_user(t, ip)) return -EFAULT;
if (t < 0 || t > dev->keycodemax || !dev->keycodesize) return -EINVAL; if (t < 0 || t > dev->keycodemax || !dev->keycodesize) return -EINVAL;
...@@ -430,7 +430,7 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct ...@@ -430,7 +430,7 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct
devfs_mk_cdev(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), devfs_mk_cdev(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
S_IFCHR|S_IRUGO|S_IWUSR, "input/event%d", minor); S_IFCHR|S_IRUGO|S_IWUSR, "input/event%d", minor);
class_simple_device_add(input_class, class_simple_device_add(input_class,
MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
dev->dev, "event%d", minor); dev->dev, "event%d", minor);
......
/* /*
The all defines and part of code (such as cs461x_*) are The all defines and part of code (such as cs461x_*) are
contributed from ALSA 0.5.8 sources. contributed from ALSA 0.5.8 sources.
See http://www.alsa-project.org/ for sources See http://www.alsa-project.org/ for sources
Tested on Linux 686 2.4.0-test9, ALSA 0.5.8a and CS4610 Tested on Linux 686 2.4.0-test9, ALSA 0.5.8a and CS4610
*/ */
...@@ -89,8 +89,8 @@ MODULE_LICENSE("GPL"); ...@@ -89,8 +89,8 @@ MODULE_LICENSE("GPL");
#define JSIO_BXOE 0x00000040 #define JSIO_BXOE 0x00000040
#define JSIO_BYOE 0x00000080 #define JSIO_BYOE 0x00000080
/* /*
The card initialization code is obfuscated; the module cs461x The card initialization code is obfuscated; the module cs461x
need to be loaded after ALSA modules initialized and something need to be loaded after ALSA modules initialized and something
played on the CS 4610 chip (see sources for details of CS4610 played on the CS 4610 chip (see sources for details of CS4610
initialization code from ALSA) initialization code from ALSA)
...@@ -112,7 +112,7 @@ MODULE_LICENSE("GPL"); ...@@ -112,7 +112,7 @@ MODULE_LICENSE("GPL");
#define BA1_DWORD_SIZE (13 * 1024 + 512) #define BA1_DWORD_SIZE (13 * 1024 + 512)
#define BA1_MEMORY_COUNT 3 #define BA1_MEMORY_COUNT 3
/* /*
Only one CS461x card is still suppoted; the code requires Only one CS461x card is still suppoted; the code requires
redesign to avoid this limitatuion. redesign to avoid this limitatuion.
*/ */
...@@ -163,7 +163,7 @@ static int cs461x_free(struct pci_dev *pdev) ...@@ -163,7 +163,7 @@ static int cs461x_free(struct pci_dev *pdev)
if(port){ if(port){
gameport_unregister_port(port); gameport_unregister_port(port);
kfree(port); kfree(port);
} }
if (ba0) iounmap(ba0); if (ba0) iounmap(ba0);
#ifdef CS461X_FULL_MAP #ifdef CS461X_FULL_MAP
if (ba1.name.data0) iounmap(ba1.name.data0); if (ba1.name.data0) iounmap(ba1.name.data0);
...@@ -187,13 +187,13 @@ static unsigned char cs461x_gameport_read(struct gameport *gameport) ...@@ -187,13 +187,13 @@ static unsigned char cs461x_gameport_read(struct gameport *gameport)
static int cs461x_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) static int cs461x_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
{ {
unsigned js1, js2, jst; unsigned js1, js2, jst;
js1 = cs461x_peekBA0(BA0_JSC1); js1 = cs461x_peekBA0(BA0_JSC1);
js2 = cs461x_peekBA0(BA0_JSC2); js2 = cs461x_peekBA0(BA0_JSC2);
jst = cs461x_peekBA0(BA0_JSPT); jst = cs461x_peekBA0(BA0_JSPT);
*buttons = (~jst >> 4) & 0x0F; *buttons = (~jst >> 4) & 0x0F;
axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF; axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;
axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF; axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;
axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF; axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
...@@ -228,7 +228,7 @@ static int __devinit cs461x_pci_probe(struct pci_dev *pdev, const struct pci_dev ...@@ -228,7 +228,7 @@ static int __devinit cs461x_pci_probe(struct pci_dev *pdev, const struct pci_dev
{ {
int rc; int rc;
struct gameport* port; struct gameport* port;
rc = pci_enable_device(pdev); rc = pci_enable_device(pdev);
if (rc) { if (rc) {
printk(KERN_ERR "cs461x: Cannot enable PCI gameport (bus %d, devfn %d) error=%d\n", printk(KERN_ERR "cs461x: Cannot enable PCI gameport (bus %d, devfn %d) error=%d\n",
...@@ -240,7 +240,7 @@ static int __devinit cs461x_pci_probe(struct pci_dev *pdev, const struct pci_dev ...@@ -240,7 +240,7 @@ static int __devinit cs461x_pci_probe(struct pci_dev *pdev, const struct pci_dev
#ifdef CS461X_FULL_MAP #ifdef CS461X_FULL_MAP
ba1_addr = pci_resource_start(pdev, 1); ba1_addr = pci_resource_start(pdev, 1);
#endif #endif
if (ba0_addr == 0 || ba0_addr == ~0 if (ba0_addr == 0 || ba0_addr == ~0
#ifdef CS461X_FULL_MAP #ifdef CS461X_FULL_MAP
|| ba1_addr == 0 || ba1_addr == ~0 || ba1_addr == 0 || ba1_addr == ~0
#endif #endif
...@@ -281,7 +281,7 @@ static int __devinit cs461x_pci_probe(struct pci_dev *pdev, const struct pci_dev ...@@ -281,7 +281,7 @@ static int __devinit cs461x_pci_probe(struct pci_dev *pdev, const struct pci_dev
memset(port, 0, sizeof(struct gameport)); memset(port, 0, sizeof(struct gameport));
pci_set_drvdata(pdev, port); pci_set_drvdata(pdev, port);
port->open = cs461x_gameport_open; port->open = cs461x_gameport_open;
port->trigger = cs461x_gameport_trigger; port->trigger = cs461x_gameport_trigger;
port->read = cs461x_gameport_read; port->read = cs461x_gameport_read;
...@@ -310,7 +310,7 @@ static void __devexit cs461x_pci_remove(struct pci_dev *pdev) ...@@ -310,7 +310,7 @@ static void __devexit cs461x_pci_remove(struct pci_dev *pdev)
{ {
cs461x_free(pdev); cs461x_free(pdev);
} }
static struct pci_driver cs461x_pci_driver = { static struct pci_driver cs461x_pci_driver = {
.name = "CS461x Gameport", .name = "CS461x Gameport",
.id_table = cs461x_pci_tbl, .id_table = cs461x_pci_tbl,
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -48,7 +48,7 @@ struct emu { ...@@ -48,7 +48,7 @@ struct emu {
int size; int size;
char phys[32]; char phys[32];
}; };
static struct pci_device_id emu_tbl[] = { static struct pci_device_id emu_tbl[] = {
{ 0x1102, 0x7002, PCI_ANY_ID, PCI_ANY_ID }, /* SB Live gameport */ { 0x1102, 0x7002, PCI_ANY_ID, PCI_ANY_ID }, /* SB Live gameport */
{ 0x1102, 0x7003, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy gameport */ { 0x1102, 0x7003, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy gameport */
...@@ -61,7 +61,7 @@ static int __devinit emu_probe(struct pci_dev *pdev, const struct pci_device_id ...@@ -61,7 +61,7 @@ static int __devinit emu_probe(struct pci_dev *pdev, const struct pci_device_id
{ {
int ioport, iolen; int ioport, iolen;
struct emu *emu; struct emu *emu;
if (pci_enable_device(pdev)) if (pci_enable_device(pdev))
return -EBUSY; return -EBUSY;
......
...@@ -111,7 +111,7 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device ...@@ -111,7 +111,7 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device
pci_set_drvdata(pci, gp); pci_set_drvdata(pci, gp);
outb(0x60, gp->gameport.io + 0x0d); /* enable joystick 1 and 2 */ outb(0x60, gp->gameport.io + 0x0d); /* enable joystick 1 and 2 */
gameport_register_port(&gp->gameport); gameport_register_port(&gp->gameport);
......
...@@ -168,7 +168,7 @@ int gameport_open(struct gameport *gameport, struct gameport_dev *dev, int mode) ...@@ -168,7 +168,7 @@ int gameport_open(struct gameport *gameport, struct gameport_dev *dev, int mode)
return -1; return -1;
gameport->dev = dev; gameport->dev = dev;
return 0; return 0;
} }
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -106,7 +106,7 @@ static int l4_cooked_read(struct gameport *gameport, int *axes, int *buttons) ...@@ -106,7 +106,7 @@ static int l4_cooked_read(struct gameport *gameport, int *axes, int *buttons)
result = 0; result = 0;
fail: outb(L4_SELECT_ANALOG, L4_PORT); fail: outb(L4_SELECT_ANALOG, L4_PORT);
return result; return result;
} }
...@@ -126,7 +126,7 @@ static int l4_open(struct gameport *gameport, int mode) ...@@ -126,7 +126,7 @@ static int l4_open(struct gameport *gameport, int mode)
static int l4_getcal(int port, int *cal) static int l4_getcal(int port, int *cal)
{ {
int i, result = -1; int i, result = -1;
outb(L4_SELECT_ANALOG, L4_PORT); outb(L4_SELECT_ANALOG, L4_PORT);
outb(L4_SELECT_DIGITAL + (port >> 2), L4_PORT); outb(L4_SELECT_DIGITAL + (port >> 2), L4_PORT);
...@@ -208,7 +208,7 @@ static int l4_calibrate(struct gameport *gameport, int *axes, int *max) ...@@ -208,7 +208,7 @@ static int l4_calibrate(struct gameport *gameport, int *axes, int *max)
return 0; return 0;
} }
static int __init l4_init(void) static int __init l4_init(void)
{ {
int cal[4] = {255,255,255,255}; int cal[4] = {255,255,255,255};
...@@ -266,7 +266,7 @@ static int __init l4_init(void) ...@@ -266,7 +266,7 @@ static int __init l4_init(void)
if (rev > 0x28) /* on 2.9+ the setcal command works correctly */ if (rev > 0x28) /* on 2.9+ the setcal command works correctly */
l4_setcal(l4->port, cal); l4_setcal(l4->port, cal);
gameport_register_port(gameport); gameport_register_port(gameport);
} }
......
...@@ -12,18 +12,18 @@ ...@@ -12,18 +12,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -59,7 +59,7 @@ struct ns558 { ...@@ -59,7 +59,7 @@ struct ns558 {
char phys[32]; char phys[32];
char name[32]; char name[32];
}; };
static LIST_HEAD(ns558_list); static LIST_HEAD(ns558_list);
/* /*
...@@ -116,7 +116,7 @@ static void ns558_isa_probe(int io) ...@@ -116,7 +116,7 @@ static void ns558_isa_probe(int io)
i = 0; i = 0;
goto out; goto out;
} }
/* /*
* And now find the number of mirrors of the port. * And now find the number of mirrors of the port.
*/ */
...@@ -292,7 +292,7 @@ void __exit ns558_exit(void) ...@@ -292,7 +292,7 @@ void __exit ns558_exit(void)
release_region(port->gameport.io & ~(port->size - 1), port->size); release_region(port->gameport.io & ~(port->size - 1), port->size);
kfree(port); kfree(port);
break; break;
default: default:
break; break;
} }
......
...@@ -83,7 +83,7 @@ static int vortex_cooked_read(struct gameport *gameport, int *axes, int *buttons ...@@ -83,7 +83,7 @@ static int vortex_cooked_read(struct gameport *gameport, int *axes, int *buttons
axes[i] = readw(vortex->io + VORTEX_AXD + i * sizeof(u32)); axes[i] = readw(vortex->io + VORTEX_AXD + i * sizeof(u32));
if (axes[i] == 0x1fff) axes[i] = -1; if (axes[i] == 0x1fff) axes[i] = -1;
} }
return 0; return 0;
} }
...@@ -122,7 +122,7 @@ static int __devinit vortex_probe(struct pci_dev *dev, const struct pci_device_i ...@@ -122,7 +122,7 @@ static int __devinit vortex_probe(struct pci_dev *dev, const struct pci_device_i
vortex->gameport.driver = vortex; vortex->gameport.driver = vortex;
vortex->gameport.fuzz = 64; vortex->gameport.fuzz = 64;
vortex->gameport.read = vortex_read; vortex->gameport.read = vortex_read;
vortex->gameport.trigger = vortex_trigger; vortex->gameport.trigger = vortex_trigger;
vortex->gameport.cooked_read = vortex_cooked_read; vortex->gameport.cooked_read = vortex_cooked_read;
...@@ -145,7 +145,7 @@ static int __devinit vortex_probe(struct pci_dev *dev, const struct pci_device_i ...@@ -145,7 +145,7 @@ static int __devinit vortex_probe(struct pci_dev *dev, const struct pci_device_i
vortex->io = vortex->base + id->driver_data; vortex->io = vortex->base + id->driver_data;
gameport_register_port(&vortex->gameport); gameport_register_port(&vortex->gameport);
printk(KERN_INFO "gameport at pci%s speed %d kHz\n", printk(KERN_INFO "gameport at pci%s speed %d kHz\n",
pci_name(dev), vortex->gameport.speed); pci_name(dev), vortex->gameport.speed);
......
...@@ -106,7 +106,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in ...@@ -106,7 +106,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
} }
break; break;
case EV_ABS: case EV_ABS:
if (code > ABS_MAX || !test_bit(code, dev->absbit)) if (code > ABS_MAX || !test_bit(code, dev->absbit))
...@@ -144,27 +144,27 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in ...@@ -144,27 +144,27 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
if (code > MSC_MAX || !test_bit(code, dev->mscbit)) if (code > MSC_MAX || !test_bit(code, dev->mscbit))
return; return;
if (dev->event) dev->event(dev, type, code, value); if (dev->event) dev->event(dev, type, code, value);
break; break;
case EV_LED: case EV_LED:
if (code > LED_MAX || !test_bit(code, dev->ledbit) || !!test_bit(code, dev->led) == value) if (code > LED_MAX || !test_bit(code, dev->ledbit) || !!test_bit(code, dev->led) == value)
return; return;
change_bit(code, dev->led); change_bit(code, dev->led);
if (dev->event) dev->event(dev, type, code, value); if (dev->event) dev->event(dev, type, code, value);
break; break;
case EV_SND: case EV_SND:
if (code > SND_MAX || !test_bit(code, dev->sndbit)) if (code > SND_MAX || !test_bit(code, dev->sndbit))
return; return;
if (dev->event) dev->event(dev, type, code, value); if (dev->event) dev->event(dev, type, code, value);
break; break;
case EV_REP: case EV_REP:
...@@ -181,7 +181,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in ...@@ -181,7 +181,7 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
break; break;
} }
if (type != EV_SYN) if (type != EV_SYN)
dev->sync = 0; dev->sync = 0;
if (dev->grab) if (dev->grab)
...@@ -282,11 +282,11 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st ...@@ -282,11 +282,11 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st
if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR) if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
if (id->id.vendor != dev->id.vendor) if (id->id.vendor != dev->id.vendor)
continue; continue;
if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT) if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
if (id->id.product != dev->id.product) if (id->id.product != dev->id.product)
continue; continue;
if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION) if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
if (id->id.version != dev->id.version) if (id->id.version != dev->id.version)
continue; continue;
...@@ -351,11 +351,11 @@ static void input_call_hotplug(char *verb, struct input_dev *dev) ...@@ -351,11 +351,11 @@ static void input_call_hotplug(char *verb, struct input_dev *dev)
} }
if (in_interrupt()) { if (in_interrupt()) {
printk(KERN_ERR "input.c: calling hotplug from interrupt\n"); printk(KERN_ERR "input.c: calling hotplug from interrupt\n");
return; return;
} }
if (!current->fs->root) { if (!current->fs->root) {
printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n"); printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n");
return; return;
} }
if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) { if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) {
printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n"); printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
...@@ -381,17 +381,17 @@ static void input_call_hotplug(char *verb, struct input_dev *dev) ...@@ -381,17 +381,17 @@ static void input_call_hotplug(char *verb, struct input_dev *dev)
envp[i++] = scratch; envp[i++] = scratch;
scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x", scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x",
dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1; dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1;
if (dev->name) { if (dev->name) {
envp[i++] = scratch; envp[i++] = scratch;
scratch += sprintf(scratch, "NAME=%s", dev->name) + 1; scratch += sprintf(scratch, "NAME=%s", dev->name) + 1;
} }
if (dev->phys) { if (dev->phys) {
envp[i++] = scratch; envp[i++] = scratch;
scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1; scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1;
} }
SPRINTF_BIT_A(evbit, "EV=", EV_MAX); SPRINTF_BIT_A(evbit, "EV=", EV_MAX);
SPRINTF_BIT_A2(keybit, "KEY=", KEY_MAX, EV_KEY); SPRINTF_BIT_A2(keybit, "KEY=", KEY_MAX, EV_KEY);
...@@ -506,7 +506,7 @@ void input_register_handler(struct input_handler *handler) ...@@ -506,7 +506,7 @@ void input_register_handler(struct input_handler *handler)
input_table[handler->minor >> 5] = handler; input_table[handler->minor >> 5] = handler;
list_add_tail(&handler->node, &input_handler_list); list_add_tail(&handler->node, &input_handler_list);
list_for_each_entry(dev, &input_dev_list, node) list_for_each_entry(dev, &input_dev_list, node)
if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
if ((id = input_match_device(handler->id_table, dev))) if ((id = input_match_device(handler->id_table, dev)))
......
/* /*
* Joystick device driver for the input driver suite. * Joystick device driver for the input driver suite.
* *
* Copyright (c) 1999-2002 Vojtech Pavlik * Copyright (c) 1999-2002 Vojtech Pavlik
* Copyright (c) 1999 Colin Van Dyke * Copyright (c) 1999 Colin Van Dyke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
...@@ -34,7 +34,7 @@ MODULE_SUPPORTED_DEVICE("input/js"); ...@@ -34,7 +34,7 @@ MODULE_SUPPORTED_DEVICE("input/js");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#define JOYDEV_MINOR_BASE 0 #define JOYDEV_MINOR_BASE 0
#define JOYDEV_MINORS 16 #define JOYDEV_MINORS 16
#define JOYDEV_BUFFER_SIZE 64 #define JOYDEV_BUFFER_SIZE 64
#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ) #define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
...@@ -115,7 +115,7 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne ...@@ -115,7 +115,7 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne
default: default:
return; return;
} }
event.time = MSECS(jiffies); event.time = MSECS(jiffies);
...@@ -449,10 +449,10 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct ...@@ -449,10 +449,10 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
} }
joydev_table[minor] = joydev; joydev_table[minor] = joydev;
devfs_mk_cdev(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), devfs_mk_cdev(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
S_IFCHR|S_IRUGO|S_IWUSR, "input/js%d", minor); S_IFCHR|S_IRUGO|S_IWUSR, "input/js%d", minor);
class_simple_device_add(input_class, class_simple_device_add(input_class,
MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
dev->dev, "js%d", minor); dev->dev, "js%d", minor);
...@@ -466,7 +466,7 @@ static void joydev_disconnect(struct input_handle *handle) ...@@ -466,7 +466,7 @@ static void joydev_disconnect(struct input_handle *handle)
joydev->exist = 0; joydev->exist = 0;
if (joydev->open) if (joydev->open)
input_close_device(handle); input_close_device(handle);
else else
joydev_free(joydev); joydev_free(joydev);
} }
......
...@@ -22,7 +22,7 @@ config JOYSTICK_ANALOG ...@@ -22,7 +22,7 @@ config JOYSTICK_ANALOG
supports many extensions, including joysticks with throttle control, supports many extensions, including joysticks with throttle control,
with rudders, additional hats and buttons compatible with CH with rudders, additional hats and buttons compatible with CH
Flightstick Pro, ThrustMaster FCS, 6 and 8 button gamepads, or Flightstick Pro, ThrustMaster FCS, 6 and 8 button gamepads, or
Saitek Cyborg joysticks. Saitek Cyborg joysticks.
Please read the file <file:Documentation/input/joystick.txt> which Please read the file <file:Documentation/input/joystick.txt> which
contains more information. contains more information.
...@@ -35,7 +35,7 @@ config JOYSTICK_A3D ...@@ -35,7 +35,7 @@ config JOYSTICK_A3D
depends on INPUT && INPUT_JOYSTICK && GAMEPORT depends on INPUT && INPUT_JOYSTICK && GAMEPORT
help help
Say Y here if you have an FPGaming or MadCatz controller using the Say Y here if you have an FPGaming or MadCatz controller using the
A3D protocol over the PC gameport. A3D protocol over the PC gameport.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called a3d. module will be called a3d.
...@@ -45,7 +45,7 @@ config JOYSTICK_ADI ...@@ -45,7 +45,7 @@ config JOYSTICK_ADI
depends on INPUT && INPUT_JOYSTICK && GAMEPORT depends on INPUT && INPUT_JOYSTICK && GAMEPORT
help help
Say Y here if you have a Logitech controller using the ADI Say Y here if you have a Logitech controller using the ADI
protocol over the PC gameport. protocol over the PC gameport.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called adi. module will be called adi.
...@@ -74,7 +74,7 @@ config JOYSTICK_GRIP ...@@ -74,7 +74,7 @@ config JOYSTICK_GRIP
depends on INPUT && INPUT_JOYSTICK && GAMEPORT depends on INPUT && INPUT_JOYSTICK && GAMEPORT
help help
Say Y here if you have a Gravis controller using the GrIP protocol Say Y here if you have a Gravis controller using the GrIP protocol
over the PC gameport. over the PC gameport.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called grip. module will be called grip.
...@@ -94,7 +94,7 @@ config JOYSTICK_GUILLEMOT ...@@ -94,7 +94,7 @@ config JOYSTICK_GUILLEMOT
depends on INPUT && INPUT_JOYSTICK && GAMEPORT depends on INPUT && INPUT_JOYSTICK && GAMEPORT
help help
Say Y here if you have a Guillemot joystick using a digital Say Y here if you have a Guillemot joystick using a digital
protocol over the PC gameport. protocol over the PC gameport.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called guillemot. module will be called guillemot.
...@@ -124,7 +124,7 @@ config JOYSTICK_TMDC ...@@ -124,7 +124,7 @@ config JOYSTICK_TMDC
depends on INPUT && INPUT_JOYSTICK && GAMEPORT depends on INPUT && INPUT_JOYSTICK && GAMEPORT
help help
Say Y here if you have a ThrustMaster controller using the Say Y here if you have a ThrustMaster controller using the
DirectConnect (BSP) protocol over the PC gameport. DirectConnect (BSP) protocol over the PC gameport.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called tmdc. module will be called tmdc.
...@@ -137,7 +137,7 @@ config JOYSTICK_WARRIOR ...@@ -137,7 +137,7 @@ config JOYSTICK_WARRIOR
select SERIO select SERIO
help help
Say Y here if you have a Logitech WingMan Warrior joystick connected Say Y here if you have a Logitech WingMan Warrior joystick connected
to your computer's serial port. to your computer's serial port.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called warrior. module will be called warrior.
...@@ -253,7 +253,7 @@ config INPUT_JOYDUMP ...@@ -253,7 +253,7 @@ config INPUT_JOYDUMP
help help
Say Y here if you want to dump data from your joystick into the system Say Y here if you want to dump data from your joystick into the system
log for debugging purposes. Say N if you are making a production log for debugging purposes. Say N if you are making a production
configuration or aren't sure. configuration or aren't sure.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called joydump. module will be called joydump.
......
...@@ -39,8 +39,8 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); ...@@ -39,8 +39,8 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("FP-Gaming Assasin 3D joystick driver"); MODULE_DESCRIPTION("FP-Gaming Assasin 3D joystick driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#define A3D_MAX_START 400 /* 400 us */ #define A3D_MAX_START 400 /* 400 us */
#define A3D_MAX_STROBE 60 /* 40 us */ #define A3D_MAX_STROBE 60 /* 40 us */
#define A3D_DELAY_READ 3 /* 3 ms */ #define A3D_DELAY_READ 3 /* 3 ms */
#define A3D_MAX_LENGTH 40 /* 40*3 bits */ #define A3D_MAX_LENGTH 40 /* 40*3 bits */
#define A3D_REFRESH_TIME HZ/50 /* 20 ms */ #define A3D_REFRESH_TIME HZ/50 /* 20 ms */
...@@ -125,7 +125,7 @@ static void a3d_read(struct a3d *a3d, unsigned char *data) ...@@ -125,7 +125,7 @@ static void a3d_read(struct a3d *a3d, unsigned char *data)
input_report_rel(dev, REL_X, ((data[5] << 6) | (data[6] << 3) | data[ 7]) - ((data[5] & 4) << 7)); input_report_rel(dev, REL_X, ((data[5] << 6) | (data[6] << 3) | data[ 7]) - ((data[5] & 4) << 7));
input_report_rel(dev, REL_Y, ((data[8] << 6) | (data[9] << 3) | data[10]) - ((data[8] & 4) << 7)); input_report_rel(dev, REL_Y, ((data[8] << 6) | (data[9] << 3) | data[10]) - ((data[8] & 4) << 7));
input_report_key(dev, BTN_RIGHT, data[2] & 1); input_report_key(dev, BTN_RIGHT, data[2] & 1);
input_report_key(dev, BTN_LEFT, data[3] & 2); input_report_key(dev, BTN_LEFT, data[3] & 2);
input_report_key(dev, BTN_MIDDLE, data[3] & 4); input_report_key(dev, BTN_MIDDLE, data[3] & 4);
...@@ -201,7 +201,7 @@ int a3d_adc_cooked_read(struct gameport *gameport, int *axes, int *buttons) ...@@ -201,7 +201,7 @@ int a3d_adc_cooked_read(struct gameport *gameport, int *axes, int *buttons)
int i; int i;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
axes[i] = (a3d->axes[i] < 254) ? a3d->axes[i] : -1; axes[i] = (a3d->axes[i] < 254) ? a3d->axes[i] : -1;
*buttons = a3d->buttons; *buttons = a3d->buttons;
return 0; return 0;
} }
...@@ -216,7 +216,7 @@ int a3d_adc_open(struct gameport *gameport, int mode) ...@@ -216,7 +216,7 @@ int a3d_adc_open(struct gameport *gameport, int mode)
if (mode != GAMEPORT_MODE_COOKED) if (mode != GAMEPORT_MODE_COOKED)
return -1; return -1;
if (!a3d->used++) if (!a3d->used++)
mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME); mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);
return 0; return 0;
} }
...@@ -239,7 +239,7 @@ static int a3d_open(struct input_dev *dev) ...@@ -239,7 +239,7 @@ static int a3d_open(struct input_dev *dev)
{ {
struct a3d *a3d = dev->private; struct a3d *a3d = dev->private;
if (!a3d->used++) if (!a3d->used++)
mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME); mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME);
return 0; return 0;
} }
...@@ -340,7 +340,7 @@ static void a3d_connect(struct gameport *gameport, struct gameport_dev *dev) ...@@ -340,7 +340,7 @@ static void a3d_connect(struct gameport *gameport, struct gameport_dev *dev)
a3d->adc.open = a3d_adc_open; a3d->adc.open = a3d_adc_open;
a3d->adc.close = a3d_adc_close; a3d->adc.close = a3d_adc_close;
a3d->adc.cooked_read = a3d_adc_cooked_read; a3d->adc.cooked_read = a3d_adc_cooked_read;
a3d->adc.fuzz = 1; a3d->adc.fuzz = 1;
a3d->adc.name = a3d_names[a3d->mode]; a3d->adc.name = a3d_names[a3d->mode];
a3d->adc.phys = a3d->adcphys; a3d->adc.phys = a3d->adcphys;
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -72,8 +72,8 @@ MODULE_LICENSE("GPL"); ...@@ -72,8 +72,8 @@ MODULE_LICENSE("GPL");
*/ */
static char *adi_names[] = { "WingMan Extreme Digital", "ThunderPad Digital", "SideCar", "CyberMan 2", static char *adi_names[] = { "WingMan Extreme Digital", "ThunderPad Digital", "SideCar", "CyberMan 2",
"WingMan Interceptor", "WingMan Formula", "WingMan GamePad", "WingMan Interceptor", "WingMan Formula", "WingMan GamePad",
"WingMan Extreme Digital 3D", "WingMan GamePad Extreme", "WingMan Extreme Digital 3D", "WingMan GamePad Extreme",
"WingMan GamePad USB", "Unknown Device %#x" }; "WingMan GamePad USB", "Unknown Device %#x" };
static char adi_wmgpe_abs[] = { ABS_X, ABS_Y, ABS_HAT0X, ABS_HAT0Y }; static char adi_wmgpe_abs[] = { ABS_X, ABS_Y, ABS_HAT0X, ABS_HAT0Y };
...@@ -178,7 +178,7 @@ static void adi_read_packet(struct adi_port *port) ...@@ -178,7 +178,7 @@ static void adi_read_packet(struct adi_port *port)
/* /*
* adi_move_bits() detects a possible 2-stream mode, and moves * adi_move_bits() detects a possible 2-stream mode, and moves
* the bits accordingly. * the bits accordingly.
*/ */
static void adi_move_bits(struct adi_port *port, int length) static void adi_move_bits(struct adi_port *port, int length)
...@@ -208,7 +208,7 @@ static inline int adi_get_bits(struct adi *adi, int count) ...@@ -208,7 +208,7 @@ static inline int adi_get_bits(struct adi *adi, int count)
int i; int i;
if ((adi->idx += count) > adi->ret) return 0; if ((adi->idx += count) > adi->ret) return 0;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
bits |= ((adi->data[adi->idx - i] >> 5) & 1) << i; bits |= ((adi->data[adi->idx - i] >> 5) & 1) << i;
return bits; return bits;
} }
...@@ -224,12 +224,12 @@ static int adi_decode(struct adi *adi) ...@@ -224,12 +224,12 @@ static int adi_decode(struct adi *adi)
int i, t; int i, t;
if (adi->ret < adi->length || adi->id != (adi_get_bits(adi, 4) | (adi_get_bits(adi, 4) << 4))) if (adi->ret < adi->length || adi->id != (adi_get_bits(adi, 4) | (adi_get_bits(adi, 4) << 4)))
return -1; return -1;
for (i = 0; i < adi->axes10; i++) for (i = 0; i < adi->axes10; i++)
input_report_abs(dev, *abs++, adi_get_bits(adi, 10)); input_report_abs(dev, *abs++, adi_get_bits(adi, 10));
for (i = 0; i < adi->axes8; i++) for (i = 0; i < adi->axes8; i++)
input_report_abs(dev, *abs++, adi_get_bits(adi, 8)); input_report_abs(dev, *abs++, adi_get_bits(adi, 8));
for (i = 0; i < adi->buttons && i < 63; i++) { for (i = 0; i < adi->buttons && i < 63; i++) {
...@@ -249,7 +249,7 @@ static int adi_decode(struct adi *adi) ...@@ -249,7 +249,7 @@ static int adi_decode(struct adi *adi)
for (i = 63; i < adi->buttons; i++) for (i = 63; i < adi->buttons; i++)
input_report_key(dev, *key++, adi_get_bits(adi, 1)); input_report_key(dev, *key++, adi_get_bits(adi, 1));
input_sync(dev); input_sync(dev);
return 0; return 0;
...@@ -294,7 +294,7 @@ static int adi_open(struct input_dev *dev) ...@@ -294,7 +294,7 @@ static int adi_open(struct input_dev *dev)
{ {
struct adi_port *port = dev->private; struct adi_port *port = dev->private;
if (!port->used++) if (!port->used++)
mod_timer(&port->timer, jiffies + ADI_REFRESH_TIME); mod_timer(&port->timer, jiffies + ADI_REFRESH_TIME);
return 0; return 0;
} }
...@@ -334,7 +334,7 @@ static void adi_id_decode(struct adi *adi, struct adi_port *port) ...@@ -334,7 +334,7 @@ static void adi_id_decode(struct adi *adi, struct adi_port *port)
return; return;
if (adi->ret < (t = adi_get_bits(adi, 10))) { if (adi->ret < (t = adi_get_bits(adi, 10))) {
printk(KERN_WARNING "adi: Short ID packet: reported: %d != read: %d\n", t, adi->ret); printk(KERN_WARNING "adi: Short ID packet: reported: %d != read: %d\n", t, adi->ret);
return; return;
} }
...@@ -498,7 +498,7 @@ static void adi_connect(struct gameport *gameport, struct gameport_dev *dev) ...@@ -498,7 +498,7 @@ static void adi_connect(struct gameport *gameport, struct gameport_dev *dev)
adi_init_digital(gameport); adi_init_digital(gameport);
adi_read_packet(port); adi_read_packet(port);
if (port->adi[0].ret >= ADI_MIN_LEN_LENGTH) if (port->adi[0].ret >= ADI_MIN_LEN_LENGTH)
adi_move_bits(port, adi_get_bits(port->adi, 10)); adi_move_bits(port, adi_get_bits(port->adi, 10));
......
...@@ -46,7 +46,7 @@ MODULE_DESCRIPTION("Driver for Amiga joysticks"); ...@@ -46,7 +46,7 @@ MODULE_DESCRIPTION("Driver for Amiga joysticks");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static int amijoy[2] = { 0, 1 }; static int amijoy[2] = { 0, 1 };
static int amijoy_nargs; static int amijoy_nargs;
module_param_array_named(map, amijoy, uint, amijoy_nargs, 0); module_param_array_named(map, amijoy, uint, amijoy_nargs, 0);
MODULE_PARM_DESC(map, "Map of attached joysticks in form of <a>,<b> (default is 0,1)"); MODULE_PARM_DESC(map, "Map of attached joysticks in form of <a>,<b> (default is 0,1)");
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -237,7 +237,7 @@ static int analog_cooked_read(struct analog_port *port) ...@@ -237,7 +237,7 @@ static int analog_cooked_read(struct analog_port *port)
loopout = (ANALOG_LOOP_TIME * port->loop) / 1000; loopout = (ANALOG_LOOP_TIME * port->loop) / 1000;
timeout = ANALOG_MAX_TIME * port->speed; timeout = ANALOG_MAX_TIME * port->speed;
local_irq_save(flags); local_irq_save(flags);
gameport_trigger(gameport); gameport_trigger(gameport);
GET_TIME(now); GET_TIME(now);
...@@ -284,7 +284,7 @@ static int analog_button_read(struct analog_port *port, char saitek, char chf) ...@@ -284,7 +284,7 @@ static int analog_button_read(struct analog_port *port, char saitek, char chf)
u = gameport_read(port->gameport); u = gameport_read(port->gameport);
if (!chf) { if (!chf) {
port->buttons = (~u >> 4) & 0xf; port->buttons = (~u >> 4) & 0xf;
return 0; return 0;
} }
...@@ -333,7 +333,7 @@ static void analog_timer(unsigned long data) ...@@ -333,7 +333,7 @@ static void analog_timer(unsigned long data)
} }
} }
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
if (port->analog[i].mask) if (port->analog[i].mask)
analog_decode(port->analog + i, port->axes, port->initial, port->buttons); analog_decode(port->analog + i, port->axes, port->initial, port->buttons);
...@@ -348,7 +348,7 @@ static int analog_open(struct input_dev *dev) ...@@ -348,7 +348,7 @@ static int analog_open(struct input_dev *dev)
{ {
struct analog_port *port = dev->private; struct analog_port *port = dev->private;
if (!port->used++) if (!port->used++)
mod_timer(&port->timer, jiffies + ANALOG_REFRESH_TIME); mod_timer(&port->timer, jiffies + ANALOG_REFRESH_TIME);
return 0; return 0;
} }
...@@ -408,7 +408,7 @@ static void analog_calibrate_timer(struct analog_port *port) ...@@ -408,7 +408,7 @@ static void analog_calibrate_timer(struct analog_port *port)
static void analog_name(struct analog *analog) static void analog_name(struct analog *analog)
{ {
sprintf(analog->name, "Analog %d-axis %d-button", sprintf(analog->name, "Analog %d-axis %d-button",
hweight8(analog->mask & ANALOG_AXES_STD), hweight8(analog->mask & ANALOG_AXES_STD),
hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTNS_CHF) * 2 + hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTNS_CHF) * 2 +
hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4); hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4);
...@@ -450,10 +450,10 @@ static void analog_init_device(struct analog_port *port, struct analog *analog, ...@@ -450,10 +450,10 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
analog->dev.close = analog_close; analog->dev.close = analog_close;
analog->dev.private = port; analog->dev.private = port;
analog->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); analog->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = j = 0; i < 4; i++) for (i = j = 0; i < 4; i++)
if (analog->mask & (1 << i)) { if (analog->mask & (1 << i)) {
t = analog_axes[j]; t = analog_axes[j];
x = port->axes[i]; x = port->axes[i];
y = (port->axes[0] + port->axes[1]) >> 1; y = (port->axes[0] + port->axes[1]) >> 1;
...@@ -481,8 +481,8 @@ static void analog_init_device(struct analog_port *port, struct analog *analog, ...@@ -481,8 +481,8 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
j++; j++;
} }
for (i = j = 0; i < 3; i++) for (i = j = 0; i < 3; i++)
if (analog->mask & analog_exts[i]) if (analog->mask & analog_exts[i])
for (x = 0; x < 2; x++) { for (x = 0; x < 2; x++) {
t = analog_hats[j++]; t = analog_hats[j++];
set_bit(t, analog->dev.absbit); set_bit(t, analog->dev.absbit);
...@@ -517,7 +517,7 @@ static void analog_init_device(struct analog_port *port, struct analog *analog, ...@@ -517,7 +517,7 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
else else
printk(" [%s timer, %d %sHz clock, %d ns res]\n", TIME_NAME, printk(" [%s timer, %d %sHz clock, %d ns res]\n", TIME_NAME,
port->speed > 10000 ? (port->speed + 800) / 1000 : port->speed, port->speed > 10000 ? (port->speed + 800) / 1000 : port->speed,
port->speed > 10000 ? "M" : "k", port->speed > 10000 ? "M" : "k",
port->speed > 10000 ? (port->loop * 1000) / (port->speed / 1000) port->speed > 10000 ? (port->loop * 1000) / (port->speed / 1000)
: (port->loop * 1000000) / port->speed); : (port->loop * 1000000) / port->speed);
} }
...@@ -580,11 +580,11 @@ static int analog_init_masks(struct analog_port *port) ...@@ -580,11 +580,11 @@ static int analog_init_masks(struct analog_port *port)
gameport_calibrate(port->gameport, port->axes, max); gameport_calibrate(port->gameport, port->axes, max);
} }
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
port->initial[i] = port->axes[i]; port->initial[i] = port->axes[i];
return -!(analog[0].mask || analog[1].mask); return -!(analog[0].mask || analog[1].mask);
} }
static int analog_init_port(struct gameport *gameport, struct gameport_dev *dev, struct analog_port *port) static int analog_init_port(struct gameport *gameport, struct gameport_dev *dev, struct analog_port *port)
...@@ -606,7 +606,7 @@ static int analog_init_port(struct gameport *gameport, struct gameport_dev *dev, ...@@ -606,7 +606,7 @@ static int analog_init_port(struct gameport *gameport, struct gameport_dev *dev,
msleep(ANALOG_MAX_TIME); msleep(ANALOG_MAX_TIME);
port->mask = (gameport_read(gameport) ^ t) & t & 0xf; port->mask = (gameport_read(gameport) ^ t) & t & 0xf;
port->fuzz = (port->speed * ANALOG_FUZZ_MAGIC) / port->loop / 1000 + ANALOG_FUZZ_BITS; port->fuzz = (port->speed * ANALOG_FUZZ_MAGIC) / port->loop / 1000 + ANALOG_FUZZ_BITS;
for (i = 0; i < ANALOG_INIT_RETRIES; i++) { for (i = 0; i < ANALOG_INIT_RETRIES; i++) {
if (!analog_cooked_read(port)) break; if (!analog_cooked_read(port)) break;
msleep(ANALOG_MAX_TIME); msleep(ANALOG_MAX_TIME);
...@@ -617,11 +617,11 @@ static int analog_init_port(struct gameport *gameport, struct gameport_dev *dev, ...@@ -617,11 +617,11 @@ static int analog_init_port(struct gameport *gameport, struct gameport_dev *dev,
msleep(ANALOG_MAX_TIME); msleep(ANALOG_MAX_TIME);
t = gameport_time(gameport, ANALOG_MAX_TIME * 1000); t = gameport_time(gameport, ANALOG_MAX_TIME * 1000);
gameport_trigger(gameport); gameport_trigger(gameport);
while ((gameport_read(port->gameport) & port->mask) && (u < t)) u++; while ((gameport_read(port->gameport) & port->mask) && (u < t)) u++;
udelay(ANALOG_SAITEK_DELAY); udelay(ANALOG_SAITEK_DELAY);
t = gameport_time(gameport, ANALOG_SAITEK_TIME); t = gameport_time(gameport, ANALOG_SAITEK_TIME);
gameport_trigger(gameport); gameport_trigger(gameport);
while ((gameport_read(port->gameport) & port->mask) && (v < t)) v++; while ((gameport_read(port->gameport) & port->mask) && (v < t)) v++;
if (v < (u >> 1)) { /* FIXME - more than one port */ if (v < (u >> 1)) { /* FIXME - more than one port */
analog_options[0] |= /* FIXME - more than one port */ analog_options[0] |= /* FIXME - more than one port */
...@@ -721,7 +721,7 @@ static void analog_parse_options(void) ...@@ -721,7 +721,7 @@ static void analog_parse_options(void)
if (!strcmp(analog_types[j].name, js[i])) { if (!strcmp(analog_types[j].name, js[i])) {
analog_options[i] = analog_types[j].value; analog_options[i] = analog_types[j].value;
break; break;
} }
if (analog_types[j].name) continue; if (analog_types[j].name) continue;
analog_options[i] = simple_strtoul(js[i], &end, 0); analog_options[i] = simple_strtoul(js[i], &end, 0);
......
...@@ -72,7 +72,7 @@ static unsigned char cobra_read_packet(struct gameport *gameport, unsigned int * ...@@ -72,7 +72,7 @@ static unsigned char cobra_read_packet(struct gameport *gameport, unsigned int *
r[i] = buf[i] = 0; r[i] = buf[i] = 0;
t[i] = COBRA_MAX_STROBE; t[i] = COBRA_MAX_STROBE;
} }
local_irq_save(flags); local_irq_save(flags);
u = gameport_read(gameport); u = gameport_read(gameport);
...@@ -140,14 +140,14 @@ static void cobra_timer(unsigned long private) ...@@ -140,14 +140,14 @@ static void cobra_timer(unsigned long private)
} }
mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME); mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME);
} }
static int cobra_open(struct input_dev *dev) static int cobra_open(struct input_dev *dev)
{ {
struct cobra *cobra = dev->private; struct cobra *cobra = dev->private;
if (!cobra->used++) if (!cobra->used++)
mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME); mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME);
return 0; return 0;
} }
...@@ -180,7 +180,7 @@ static void cobra_connect(struct gameport *gameport, struct gameport_dev *dev) ...@@ -180,7 +180,7 @@ static void cobra_connect(struct gameport *gameport, struct gameport_dev *dev)
cobra->exists = cobra_read_packet(gameport, data); cobra->exists = cobra_read_packet(gameport, data);
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
if ((cobra->exists >> i) & data[i] & 1) { if ((cobra->exists >> i) & data[i] & 1) {
printk(KERN_WARNING "cobra.c: Device %d on %s has the Ext bit set. ID is: %d" printk(KERN_WARNING "cobra.c: Device %d on %s has the Ext bit set. ID is: %d"
" Contact vojtech@ucw.cz\n", i, gameport->phys, (data[i] >> 2) & 7); " Contact vojtech@ucw.cz\n", i, gameport->phys, (data[i] >> 2) & 7);
...@@ -205,7 +205,7 @@ static void cobra_connect(struct gameport *gameport, struct gameport_dev *dev) ...@@ -205,7 +205,7 @@ static void cobra_connect(struct gameport *gameport, struct gameport_dev *dev)
cobra->dev[i].id.vendor = GAMEPORT_ID_VENDOR_CREATIVE; cobra->dev[i].id.vendor = GAMEPORT_ID_VENDOR_CREATIVE;
cobra->dev[i].id.product = 0x0008; cobra->dev[i].id.product = 0x0008;
cobra->dev[i].id.version = 0x0100; cobra->dev[i].id.version = 0x0100;
cobra->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); cobra->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
cobra->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y); cobra->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
......
...@@ -14,14 +14,14 @@ ...@@ -14,14 +14,14 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
...@@ -95,7 +95,7 @@ __obsolete_setup("db9_3="); ...@@ -95,7 +95,7 @@ __obsolete_setup("db9_3=");
struct db9 { struct db9 {
struct input_dev dev[DB9_MAX_DEVICES]; struct input_dev dev[DB9_MAX_DEVICES];
struct timer_list timer; struct timer_list timer;
struct pardevice *pd; struct pardevice *pd;
int mode; int mode;
int used; int used;
char phys[2][32]; char phys[2][32];
...@@ -188,7 +188,7 @@ static unsigned char db9_saturn_read_analog(struct parport *port, int type, int ...@@ -188,7 +188,7 @@ static unsigned char db9_saturn_read_analog(struct parport *port, int type, int
} }
/* /*
* db9_saturn_read_packet() reads whole saturn packet at connector * db9_saturn_read_packet() reads whole saturn packet at connector
* and returns device identifier code. * and returns device identifier code.
*/ */
static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char *data, int type, int powered) static unsigned char db9_saturn_read_packet(struct parport *port, unsigned char *data, int type, int powered)
...@@ -481,16 +481,16 @@ static void db9_timer(unsigned long private) ...@@ -481,16 +481,16 @@ static void db9_timer(unsigned long private)
input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1)); input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1)); input_report_abs(dev, ABS_Y, (data & DB9_DOWN ? 0 : 1) - (data & DB9_UP ? 0 : 1));
parport_write_control(port, 0x0a); parport_write_control(port, 0x0a);
for (i = 0; i < 7; i++) { for (i = 0; i < 7; i++) {
data = parport_read_data(port); data = parport_read_data(port);
parport_write_control(port, 0x02); parport_write_control(port, 0x02);
parport_write_control(port, 0x0a); parport_write_control(port, 0x0a);
input_report_key(dev, db9_cd32_btn[i], ~data & DB9_FIRE2); input_report_key(dev, db9_cd32_btn[i], ~data & DB9_FIRE2);
} }
parport_write_control(port, 0x00); parport_write_control(port, 0x00);
break; break;
} }
...@@ -600,7 +600,7 @@ static struct db9 __init *db9_probe(int *config, int nargs) ...@@ -600,7 +600,7 @@ static struct db9 __init *db9_probe(int *config, int nargs)
db9->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); db9->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (j = 0; j < db9_buttons[db9->mode]; j++) for (j = 0; j < db9_buttons[db9->mode]; j++)
set_bit(db9_btn[db9->mode][j], db9->dev[i].keybit); set_bit(db9_btn[db9->mode][j], db9->dev[i].keybit);
for (j = 0; j < db9_num_axis[db9->mode]; j++) { for (j = 0; j < db9_num_axis[db9->mode]; j++) {
set_bit(db9_abs[j], db9->dev[i].absbit); set_bit(db9_abs[j], db9->dev[i].absbit);
if (j < 2) { if (j < 2) {
...@@ -635,7 +635,7 @@ void __exit db9_exit(void) ...@@ -635,7 +635,7 @@ void __exit db9_exit(void)
{ {
int i, j; int i, j;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
if (db9_base[i]) { if (db9_base[i]) {
for (j = 0; j < min(db9_max_pads[db9_base[i]->mode], DB9_MAX_DEVICES); j++) for (j = 0; j < min(db9_max_pads[db9_base[i]->mode], DB9_MAX_DEVICES); j++)
input_unregister_device(db9_base[i]->dev + j); input_unregister_device(db9_base[i]->dev + j);
......
...@@ -15,14 +15,14 @@ ...@@ -15,14 +15,14 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
...@@ -70,13 +70,13 @@ __obsolete_setup("gc_3="); ...@@ -70,13 +70,13 @@ __obsolete_setup("gc_3=");
#define GC_NES4 3 #define GC_NES4 3
#define GC_MULTI 4 #define GC_MULTI 4
#define GC_MULTI2 5 #define GC_MULTI2 5
#define GC_N64 6 #define GC_N64 6
#define GC_PSX 7 #define GC_PSX 7
#define GC_MAX 7 #define GC_MAX 7
#define GC_REFRESH_TIME HZ/100 #define GC_REFRESH_TIME HZ/100
struct gc { struct gc {
struct pardevice *pd; struct pardevice *pd;
struct input_dev dev[5]; struct input_dev dev[5];
...@@ -104,7 +104,7 @@ static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, ...@@ -104,7 +104,7 @@ static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL,
#define GC_N64_DELAY 133 /* delay between transmit request, and response ready (us) */ #define GC_N64_DELAY 133 /* delay between transmit request, and response ready (us) */
#define GC_N64_REQUEST 0x1dd1111111ULL /* the request data command (encoded for 000000011) */ #define GC_N64_REQUEST 0x1dd1111111ULL /* the request data command (encoded for 000000011) */
#define GC_N64_DWS 3 /* delay between write segments (required for sound playback because of ISA DMA) */ #define GC_N64_DWS 3 /* delay between write segments (required for sound playback because of ISA DMA) */
/* GC_N64_DWS > 24 is known to fail */ /* GC_N64_DWS > 24 is known to fail */
#define GC_N64_POWER_W 0xe2 /* power during write (transmit request) */ #define GC_N64_POWER_W 0xe2 /* power during write (transmit request) */
#define GC_N64_POWER_R 0xfd /* power during read */ #define GC_N64_POWER_R 0xfd /* power during read */
#define GC_N64_OUT 0x1d /* output bits to the 4 pads */ #define GC_N64_OUT 0x1d /* output bits to the 4 pads */
...@@ -113,8 +113,8 @@ static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, ...@@ -113,8 +113,8 @@ static short gc_n64_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL,
/* than 123 us */ /* than 123 us */
#define GC_N64_CLOCK 0x02 /* clock bits for read */ #define GC_N64_CLOCK 0x02 /* clock bits for read */
/* /*
* gc_n64_read_packet() reads an N64 packet. * gc_n64_read_packet() reads an N64 packet.
* Each pad uses one bit per byte. So all pads connected to this port are read in parallel. * Each pad uses one bit per byte. So all pads connected to this port are read in parallel.
*/ */
...@@ -224,7 +224,7 @@ static void gc_multi_read_packet(struct gc *gc, int length, unsigned char *data) ...@@ -224,7 +224,7 @@ static void gc_multi_read_packet(struct gc *gc, int length, unsigned char *data)
* http://www.dim.com/~mackys/psxmemcard/ps-eng2.txt * http://www.dim.com/~mackys/psxmemcard/ps-eng2.txt
* http://www.gamesx.com/controldata/psxcont/psxcont.htm * http://www.gamesx.com/controldata/psxcont/psxcont.htm
* ftp://milano.usal.es/pablo/ * ftp://milano.usal.es/pablo/
* *
*/ */
#define GC_PSX_DELAY 25 /* 25 usec */ #define GC_PSX_DELAY 25 /* 25 usec */
...@@ -331,13 +331,13 @@ static void gc_timer(unsigned long private) ...@@ -331,13 +331,13 @@ static void gc_timer(unsigned long private)
s = gc_status_bit[i]; s = gc_status_bit[i];
if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) { if (s & gc->pads[GC_N64] & ~(data[8] | data[9])) {
signed char axes[2]; signed char axes[2];
axes[0] = axes[1] = 0; axes[0] = axes[1] = 0;
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
if (data[23 - j] & s) axes[0] |= 1 << j; if (data[23 - j] & s) axes[0] |= 1 << j;
if (data[31 - j] & s) axes[1] |= 1 << j; if (data[31 - j] & s) axes[1] |= 1 << j;
} }
input_report_abs(dev + i, ABS_X, axes[0]); input_report_abs(dev + i, ABS_X, axes[0]);
...@@ -588,7 +588,7 @@ static struct gc __init *gc_probe(int *config, int nargs) ...@@ -588,7 +588,7 @@ static struct gc __init *gc_probe(int *config, int nargs)
break; break;
case GC_PSX: case GC_PSX:
psx = gc_psx_read_packet(gc, data); psx = gc_psx_read_packet(gc, data);
switch(psx) { switch(psx) {
...@@ -629,7 +629,7 @@ static struct gc __init *gc_probe(int *config, int nargs) ...@@ -629,7 +629,7 @@ static struct gc __init *gc_probe(int *config, int nargs)
} }
sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i); sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i);
gc->dev[i].name = gc_names[config[i + 1]]; gc->dev[i].name = gc_names[config[i + 1]];
gc->dev[i].phys = gc->phys[i]; gc->dev[i].phys = gc->phys[i];
gc->dev[i].id.bustype = BUS_PARPORT; gc->dev[i].id.bustype = BUS_PARPORT;
...@@ -646,7 +646,7 @@ static struct gc __init *gc_probe(int *config, int nargs) ...@@ -646,7 +646,7 @@ static struct gc __init *gc_probe(int *config, int nargs)
return NULL; return NULL;
} }
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
if (gc->pads[0] & gc_status_bit[i]) { if (gc->pads[0] & gc_status_bit[i]) {
input_register_device(gc->dev + i); input_register_device(gc->dev + i);
printk(KERN_INFO "input: %s on %s\n", gc->dev[i].name, gc->pd->port->name); printk(KERN_INFO "input: %s on %s\n", gc->dev[i].name, gc->pd->port->name);
...@@ -675,7 +675,7 @@ void __exit gc_exit(void) ...@@ -675,7 +675,7 @@ void __exit gc_exit(void)
if (gc_base[i]) { if (gc_base[i]) {
for (j = 0; j < 5; j++) for (j = 0; j < 5; j++)
if (gc_base[i]->pads[0] & gc_status_bit[j]) if (gc_base[i]->pads[0] & gc_status_bit[j])
input_unregister_device(gc_base[i]->dev + j); input_unregister_device(gc_base[i]->dev + j);
parport_unregister_device(gc_base[i]->pd); parport_unregister_device(gc_base[i]->pd);
} }
} }
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -223,7 +223,7 @@ static int gf2k_open(struct input_dev *dev) ...@@ -223,7 +223,7 @@ static int gf2k_open(struct input_dev *dev)
{ {
struct gf2k *gf2k = dev->private; struct gf2k *gf2k = dev->private;
if (!gf2k->used++) if (!gf2k->used++)
mod_timer(&gf2k->timer, jiffies + GF2K_REFRESH); mod_timer(&gf2k->timer, jiffies + GF2K_REFRESH);
return 0; return 0;
} }
...@@ -324,7 +324,7 @@ static void gf2k_connect(struct gameport *gameport, struct gameport_dev *dev) ...@@ -324,7 +324,7 @@ static void gf2k_connect(struct gameport *gameport, struct gameport_dev *dev)
for (i = 0; i < gf2k_axes[gf2k->id]; i++) { for (i = 0; i < gf2k_axes[gf2k->id]; i++) {
gf2k->dev.absmax[gf2k_abs[i]] = (i < 2) ? gf2k->dev.abs[gf2k_abs[i]] * 2 - 32 : gf2k->dev.absmax[gf2k_abs[i]] = (i < 2) ? gf2k->dev.abs[gf2k_abs[i]] * 2 - 32 :
gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32; gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32;
gf2k->dev.absmin[gf2k_abs[i]] = 32; gf2k->dev.absmin[gf2k_abs[i]] = 32;
gf2k->dev.absfuzz[gf2k_abs[i]] = 8; gf2k->dev.absfuzz[gf2k_abs[i]] = 8;
gf2k->dev.absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0; gf2k->dev.absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0;
......
...@@ -48,8 +48,8 @@ MODULE_LICENSE("GPL"); ...@@ -48,8 +48,8 @@ MODULE_LICENSE("GPL");
#define GRIP_STROBE_GPP 200 /* 200 us */ #define GRIP_STROBE_GPP 200 /* 200 us */
#define GRIP_LENGTH_XT 4 #define GRIP_LENGTH_XT 4
#define GRIP_STROBE_XT 64 /* 64 us */ #define GRIP_STROBE_XT 64 /* 64 us */
#define GRIP_MAX_CHUNKS_XT 10 #define GRIP_MAX_CHUNKS_XT 10
#define GRIP_MAX_BITS_XT 30 #define GRIP_MAX_BITS_XT 30
#define GRIP_REFRESH_TIME HZ/50 /* 20 ms */ #define GRIP_REFRESH_TIME HZ/50 /* 20 ms */
...@@ -153,7 +153,7 @@ static int grip_xt_read_packet(struct gameport *gameport, int shift, unsigned in ...@@ -153,7 +153,7 @@ static int grip_xt_read_packet(struct gameport *gameport, int shift, unsigned in
buf = (buf << 1) | (u >> 1); buf = (buf << 1) | (u >> 1);
t = strobe; t = strobe;
i++; i++;
} else } else
if ((((u ^ v) & (v ^ w)) >> 1) & ~(u | v | w) & 1) { if ((((u ^ v) & (v ^ w)) >> 1) & ~(u | v | w) & 1) {
if (i == 20) { if (i == 20) {
......
...@@ -69,7 +69,7 @@ struct grip_mp { ...@@ -69,7 +69,7 @@ struct grip_mp {
#define IO_MODE_FAST 0x0200 /* Used 3 data bits per gameport read */ #define IO_MODE_FAST 0x0200 /* Used 3 data bits per gameport read */
#define IO_SLOT_CHANGE 0x0800 /* Multiport physical slot status changed */ #define IO_SLOT_CHANGE 0x0800 /* Multiport physical slot status changed */
#define IO_DONE 0x1000 /* Multiport is done sending packets */ #define IO_DONE 0x1000 /* Multiport is done sending packets */
#define IO_RETRY 0x4000 /* Try again later to get packet */ #define IO_RETRY 0x4000 /* Try again later to get packet */
#define IO_RESET 0x8000 /* Force multiport to resend all packets */ #define IO_RESET 0x8000 /* Force multiport to resend all packets */
/* /*
...@@ -144,8 +144,8 @@ static inline int poll_until(u8 onbits, u8 offbits, int u_sec, struct gameport* ...@@ -144,8 +144,8 @@ static inline int poll_until(u8 onbits, u8 offbits, int u_sec, struct gameport*
/* /*
* Gets a 28-bit packet from the multiport. * Gets a 28-bit packet from the multiport.
* *
* After getting a packet successfully, commands encoded by sendcode may * After getting a packet successfully, commands encoded by sendcode may
* be sent to the multiport. * be sent to the multiport.
* *
* The multiport clock value is reflected in gameport bit B4. * The multiport clock value is reflected in gameport bit B4.
* *
...@@ -169,7 +169,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa ...@@ -169,7 +169,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
*packet = 0; *packet = 0;
raw_data = gameport_read(gameport); raw_data = gameport_read(gameport);
if (raw_data & 1) if (raw_data & 1)
return IO_RETRY; return IO_RETRY;
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
...@@ -183,11 +183,11 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa ...@@ -183,11 +183,11 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
if (raw_data & 0x31) if (raw_data & 0x31)
return IO_RESET; return IO_RESET;
gameport_trigger(gameport); gameport_trigger(gameport);
if (!poll_until(0x10, 0, 308, gameport, &raw_data)) if (!poll_until(0x10, 0, 308, gameport, &raw_data))
return IO_RESET; return IO_RESET;
} else } else
return IO_RETRY; return IO_RETRY;
/* Determine packet transfer mode and prepare for packet construction. */ /* Determine packet transfer mode and prepare for packet construction. */
...@@ -195,7 +195,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa ...@@ -195,7 +195,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
if (raw_data & 0x20) { /* 3 data bits/read */ if (raw_data & 0x20) { /* 3 data bits/read */
portvals |= raw_data >> 4; /* Compare B4-B7 before & after trigger */ portvals |= raw_data >> 4; /* Compare B4-B7 before & after trigger */
if (portvals != 0xb) if (portvals != 0xb)
return 0; return 0;
data_mask = 7; data_mask = 7;
bits_per_read = 3; bits_per_read = 3;
...@@ -221,7 +221,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa ...@@ -221,7 +221,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
return IO_RESET; return IO_RESET;
} }
if (raw_data) if (raw_data)
return IO_RESET; return IO_RESET;
/* If 3 bits/read used, drop from 30 bits to 28. */ /* If 3 bits/read used, drop from 30 bits to 28. */
...@@ -231,7 +231,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa ...@@ -231,7 +231,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
pkt = (pkt >> 2) | 0xf0000000; pkt = (pkt >> 2) | 0xf0000000;
} }
if (bit_parity(pkt) == 1) if (bit_parity(pkt) == 1)
return IO_RESET; return IO_RESET;
/* Acknowledge packet receipt */ /* Acknowledge packet receipt */
...@@ -251,10 +251,10 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa ...@@ -251,10 +251,10 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
/* Return if we just wanted the packet or multiport wants to send more */ /* Return if we just wanted the packet or multiport wants to send more */
*packet = pkt; *packet = pkt;
if ((sendflags == 0) || ((sendflags & IO_RETRY) && !(pkt & PACKET_MP_DONE))) if ((sendflags == 0) || ((sendflags & IO_RETRY) && !(pkt & PACKET_MP_DONE)))
return IO_GOT_PACKET; return IO_GOT_PACKET;
if (pkt & PACKET_MP_MORE) if (pkt & PACKET_MP_MORE)
return IO_GOT_PACKET | IO_RETRY; return IO_GOT_PACKET | IO_RETRY;
...@@ -277,7 +277,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa ...@@ -277,7 +277,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
if (!poll_until(0x30, 0, 193, gameport, &raw_data)) if (!poll_until(0x30, 0, 193, gameport, &raw_data))
return IO_GOT_PACKET | IO_RESET; return IO_GOT_PACKET | IO_RESET;
if (raw_data & 1) if (raw_data & 1)
return IO_GOT_PACKET | IO_RESET; return IO_GOT_PACKET | IO_RESET;
if (sendcode & 1) if (sendcode & 1)
...@@ -429,19 +429,19 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags) ...@@ -429,19 +429,19 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags)
strange_code = joytype; strange_code = joytype;
} }
} }
return flags; return flags;
} }
/* /*
* Returns true if all multiport slot states appear valid. * Returns true if all multiport slot states appear valid.
*/ */
static int slots_valid(struct grip_mp *grip) static int slots_valid(struct grip_mp *grip)
{ {
int flags, slot, invalid = 0, active = 0; int flags, slot, invalid = 0, active = 0;
flags = get_and_decode_packet(grip, 0); flags = get_and_decode_packet(grip, 0);
if (!(flags & IO_GOT_PACKET)) if (!(flags & IO_GOT_PACKET))
return 0; return 0;
for (slot = 0; slot < 4; slot++) { for (slot = 0; slot < 4; slot++) {
...@@ -463,7 +463,7 @@ static int slots_valid(struct grip_mp *grip) ...@@ -463,7 +463,7 @@ static int slots_valid(struct grip_mp *grip)
* Returns whether the multiport was placed into digital mode and * Returns whether the multiport was placed into digital mode and
* able to communicate its state successfully. * able to communicate its state successfully.
*/ */
static int multiport_init(struct grip_mp *grip) static int multiport_init(struct grip_mp *grip)
{ {
int dig_mode, initialized = 0, tries = 0; int dig_mode, initialized = 0, tries = 0;
...@@ -481,7 +481,7 @@ static int multiport_init(struct grip_mp *grip) ...@@ -481,7 +481,7 @@ static int multiport_init(struct grip_mp *grip)
dbg("multiport_init(): unable to achieve digital mode.\n"); dbg("multiport_init(): unable to achieve digital mode.\n");
return 0; return 0;
} }
/* Get packets, store multiport state, and check state's validity */ /* Get packets, store multiport state, and check state's validity */
for (tries = 0; tries < 4096; tries++) { for (tries = 0; tries < 4096; tries++) {
if ( slots_valid(grip) ) { if ( slots_valid(grip) ) {
...@@ -520,9 +520,9 @@ static void report_slot(struct grip_mp *grip, int slot) ...@@ -520,9 +520,9 @@ static void report_slot(struct grip_mp *grip, int slot)
} }
/* /*
* Get the multiport state. * Get the multiport state.
*/ */
static void get_and_report_mp_state(struct grip_mp *grip) static void get_and_report_mp_state(struct grip_mp *grip)
{ {
int i, npkts, flags; int i, npkts, flags;
...@@ -538,7 +538,7 @@ static void get_and_report_mp_state(struct grip_mp *grip) ...@@ -538,7 +538,7 @@ static void get_and_report_mp_state(struct grip_mp *grip)
break; break;
} }
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
if (grip->dirty[i]) if (grip->dirty[i])
report_slot(grip, i); report_slot(grip, i);
} }
...@@ -546,7 +546,7 @@ static void get_and_report_mp_state(struct grip_mp *grip) ...@@ -546,7 +546,7 @@ static void get_and_report_mp_state(struct grip_mp *grip)
/* /*
* Called when a joystick device file is opened * Called when a joystick device file is opened
*/ */
static int grip_open(struct input_dev *dev) static int grip_open(struct input_dev *dev)
{ {
struct grip_mp *grip = dev->private; struct grip_mp *grip = dev->private;
...@@ -607,7 +607,7 @@ static void register_slot(int slot, struct grip_mp *grip) ...@@ -607,7 +607,7 @@ static void register_slot(int slot, struct grip_mp *grip)
/* /*
* Repeatedly polls the multiport and generates events. * Repeatedly polls the multiport and generates events.
*/ */
static void grip_timer(unsigned long private) static void grip_timer(unsigned long private)
{ {
struct grip_mp *grip = (void*) private; struct grip_mp *grip = (void*) private;
......
...@@ -45,7 +45,7 @@ MODULE_LICENSE("GPL"); ...@@ -45,7 +45,7 @@ MODULE_LICENSE("GPL");
#define GUILLEMOT_MAX_LENGTH 17 /* 17 bytes */ #define GUILLEMOT_MAX_LENGTH 17 /* 17 bytes */
#define GUILLEMOT_REFRESH_TIME HZ/50 /* 20 ms */ #define GUILLEMOT_REFRESH_TIME HZ/50 /* 20 ms */
static short guillemot_abs_pad[] = static short guillemot_abs_pad[] =
{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, -1 }; { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, -1 };
static short guillemot_btn_pad[] = static short guillemot_btn_pad[] =
...@@ -160,7 +160,7 @@ static int guillemot_open(struct input_dev *dev) ...@@ -160,7 +160,7 @@ static int guillemot_open(struct input_dev *dev)
{ {
struct guillemot *guillemot = dev->private; struct guillemot *guillemot = dev->private;
if (!guillemot->used++) if (!guillemot->used++)
mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME); mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME);
return 0; return 0;
} }
...@@ -211,7 +211,7 @@ static void guillemot_connect(struct gameport *gameport, struct gameport_dev *de ...@@ -211,7 +211,7 @@ static void guillemot_connect(struct gameport *gameport, struct gameport_dev *de
if (!guillemot_type[i].name) { if (!guillemot_type[i].name) {
printk(KERN_WARNING "guillemot.c: Unknown joystick on %s. [ %02x%02x:%04x, ver %d.%02d ]\n", printk(KERN_WARNING "guillemot.c: Unknown joystick on %s. [ %02x%02x:%04x, ver %d.%02d ]\n",
gameport->phys, data[12], data[13], data[11], data[14], data[15]); gameport->phys, data[12], data[13], data[11], data[14], data[15]);
goto fail2; goto fail2;
} }
sprintf(guillemot->phys, "%s/input0", gameport->phys); sprintf(guillemot->phys, "%s/input0", gameport->phys);
...@@ -237,7 +237,7 @@ static void guillemot_connect(struct gameport *gameport, struct gameport_dev *de ...@@ -237,7 +237,7 @@ static void guillemot_connect(struct gameport *gameport, struct gameport_dev *de
guillemot->dev.absmax[t] = 255; guillemot->dev.absmax[t] = 255;
} }
if (guillemot->type->hat) if (guillemot->type->hat)
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
t = ABS_HAT0X + i; t = ABS_HAT0X + i;
set_bit(t, guillemot->dev.absbit); set_bit(t, guillemot->dev.absbit);
......
...@@ -17,7 +17,7 @@ config JOYSTICK_IFORCE_USB ...@@ -17,7 +17,7 @@ config JOYSTICK_IFORCE_USB
depends on JOYSTICK_IFORCE && (JOYSTICK_IFORCE=m || USB=y) && USB depends on JOYSTICK_IFORCE && (JOYSTICK_IFORCE=m || USB=y) && USB
help help
Say Y here if you have an I-Force joystick or steering wheel Say Y here if you have an I-Force joystick or steering wheel
connected to your USB port. connected to your USB port.
config JOYSTICK_IFORCE_232 config JOYSTICK_IFORCE_232
bool "I-Force Serial joysticks and wheels" bool "I-Force Serial joysticks and wheels"
......
...@@ -7,14 +7,14 @@ ...@@ -7,14 +7,14 @@
# Goal definition # Goal definition
iforce-objs := iforce-ff.o iforce-main.o iforce-packets.o iforce-objs := iforce-ff.o iforce-main.o iforce-packets.o
obj-$(CONFIG_JOYSTICK_IFORCE) += iforce.o obj-$(CONFIG_JOYSTICK_IFORCE) += iforce.o
ifeq ($(CONFIG_JOYSTICK_IFORCE_232),y) ifeq ($(CONFIG_JOYSTICK_IFORCE_232),y)
iforce-objs += iforce-serio.o iforce-objs += iforce-serio.o
endif endif
ifeq ($(CONFIG_JOYSTICK_IFORCE_USB),y) ifeq ($(CONFIG_JOYSTICK_IFORCE_USB),y)
iforce-objs += iforce-usb.o iforce-objs += iforce-usb.o
endif endif
EXTRA_CFLAGS = -Werror-implicit-function-declaration EXTRA_CFLAGS = -Werror-implicit-function-declaration
...@@ -195,7 +195,7 @@ static unsigned char find_button(struct iforce *iforce, signed short button) ...@@ -195,7 +195,7 @@ static unsigned char find_button(struct iforce *iforce, signed short button)
} }
/* /*
* Analyse the changes in an effect, and tell if we need to send an condition * Analyse the changes in an effect, and tell if we need to send an condition
* parameter packet * parameter packet
*/ */
static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new) static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new)
...@@ -372,7 +372,7 @@ int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int ...@@ -372,7 +372,7 @@ int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int
int core_err = 0; int core_err = 0;
if (!is_update || need_period_modifier(iforce, effect)) { if (!is_update || need_period_modifier(iforce, effect)) {
param1_err = make_period_modifier(iforce, mod1_chunk, param1_err = make_period_modifier(iforce, mod1_chunk,
is_update, is_update,
effect->u.periodic.magnitude, effect->u.periodic.offset, effect->u.periodic.magnitude, effect->u.periodic.offset,
effect->u.periodic.period, effect->u.periodic.phase); effect->u.periodic.period, effect->u.periodic.phase);
......
...@@ -166,7 +166,7 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect) ...@@ -166,7 +166,7 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
else { else {
/* We want to update an effect */ /* We want to update an effect */
if (!CHECK_OWNERSHIP(effect->id, iforce)) return -EACCES; if (!CHECK_OWNERSHIP(effect->id, iforce)) return -EACCES;
/* Parameter type cannot be updated */ /* Parameter type cannot be updated */
if (effect->type != iforce->core_effects[effect->id].effect.type) if (effect->type != iforce->core_effects[effect->id].effect.type)
return -EINVAL; return -EINVAL;
...@@ -273,7 +273,7 @@ static int iforce_flush(struct input_dev *dev, struct file *file) ...@@ -273,7 +273,7 @@ static int iforce_flush(struct input_dev *dev, struct file *file)
if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) && if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
current->pid == iforce->core_effects[i].owner) { current->pid == iforce->core_effects[i].owner) {
/* Stop effect */ /* Stop effect */
input_report_ff(dev, i, 0); input_report_ff(dev, i, 0);
......
...@@ -56,7 +56,7 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data) ...@@ -56,7 +56,7 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
int empty; int empty;
int head, tail; int head, tail;
unsigned long flags; unsigned long flags;
/* /*
* Update head and tail of xmit buffer * Update head and tail of xmit buffer
*/ */
...@@ -108,7 +108,7 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data) ...@@ -108,7 +108,7 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
break; break;
#endif #endif
#ifdef CONFIG_JOYSTICK_IFORCE_USB #ifdef CONFIG_JOYSTICK_IFORCE_USB
case IFORCE_USB: case IFORCE_USB:
if (iforce->usbdev && empty && if (iforce->usbdev && empty &&
!test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)) { !test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)) {
......
...@@ -62,7 +62,7 @@ void iforce_serial_xmit(struct iforce *iforce) ...@@ -62,7 +62,7 @@ void iforce_serial_xmit(struct iforce *iforce)
cs ^= iforce->xmit.buf[iforce->xmit.tail]; cs ^= iforce->xmit.buf[iforce->xmit.tail];
XMIT_INC(iforce->xmit.tail, 1); XMIT_INC(iforce->xmit.tail, 1);
} }
serio_write(iforce->serio, cs); serio_write(iforce->serio, cs);
if (test_and_clear_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags)) if (test_and_clear_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags))
......
...@@ -141,7 +141,7 @@ struct iforce { ...@@ -141,7 +141,7 @@ struct iforce {
struct circ_buf xmit; struct circ_buf xmit;
unsigned char xmit_data[XMIT_SIZE]; unsigned char xmit_data[XMIT_SIZE];
long xmit_flags[1]; long xmit_flags[1];
/* Force Feedback */ /* Force Feedback */
wait_queue_head_t wait; wait_queue_head_t wait;
struct resource device_memory; struct resource device_memory;
......
...@@ -63,7 +63,7 @@ struct interact { ...@@ -63,7 +63,7 @@ struct interact {
char phys[32]; char phys[32];
}; };
static short interact_abs_hhfx[] = static short interact_abs_hhfx[] =
{ ABS_RX, ABS_RY, ABS_X, ABS_Y, ABS_HAT0X, ABS_HAT0Y, -1 }; { ABS_RX, ABS_RY, ABS_X, ABS_Y, ABS_HAT0X, ABS_HAT0Y, -1 };
static short interact_abs_pp8d[] = static short interact_abs_pp8d[] =
{ ABS_X, ABS_Y, -1 }; { ABS_X, ABS_Y, -1 };
...@@ -166,7 +166,7 @@ static void interact_timer(unsigned long private) ...@@ -166,7 +166,7 @@ static void interact_timer(unsigned long private)
case INTERACT_TYPE_PP8D: case INTERACT_TYPE_PP8D:
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
input_report_abs(dev, interact_abs_pp8d[i], input_report_abs(dev, interact_abs_pp8d[i],
((data[0] >> ((i << 1) + 20)) & 1) - ((data[0] >> ((i << 1) + 21)) & 1)); ((data[0] >> ((i << 1) + 20)) & 1) - ((data[0] >> ((i << 1) + 21)) & 1));
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
...@@ -190,7 +190,7 @@ static int interact_open(struct input_dev *dev) ...@@ -190,7 +190,7 @@ static int interact_open(struct input_dev *dev)
{ {
struct interact *interact = dev->private; struct interact *interact = dev->private;
if (!interact->used++) if (!interact->used++)
mod_timer(&interact->timer, jiffies + INTERACT_REFRESH_TIME); mod_timer(&interact->timer, jiffies + INTERACT_REFRESH_TIME);
return 0; return 0;
} }
...@@ -242,7 +242,7 @@ static void interact_connect(struct gameport *gameport, struct gameport_dev *dev ...@@ -242,7 +242,7 @@ static void interact_connect(struct gameport *gameport, struct gameport_dev *dev
if (!interact_type[i].length) { if (!interact_type[i].length) {
printk(KERN_WARNING "interact.c: Unknown joystick on %s. [len %d d0 %08x d1 %08x i2 %08x]\n", printk(KERN_WARNING "interact.c: Unknown joystick on %s. [len %d d0 %08x d1 %08x i2 %08x]\n",
gameport->phys, i, data[0], data[1], data[2]); gameport->phys, i, data[0], data[1], data[2]);
goto fail2; goto fail2;
} }
sprintf(interact->phys, "%s/input0", gameport->phys); sprintf(interact->phys, "%s/input0", gameport->phys);
......
...@@ -12,18 +12,18 @@ ...@@ -12,18 +12,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -63,7 +63,7 @@ static void __devinit joydump_connect(struct gameport *gameport, struct gameport ...@@ -63,7 +63,7 @@ static void __devinit joydump_connect(struct gameport *gameport, struct gameport
printk(KERN_INFO "joydump: | Raw mode not available - trying cooked. |\n"); printk(KERN_INFO "joydump: | Raw mode not available - trying cooked. |\n");
if (gameport_open(gameport, dev, GAMEPORT_MODE_COOKED)) { if (gameport_open(gameport, dev, GAMEPORT_MODE_COOKED)) {
printk(KERN_INFO "joydump: | Cooked not available either. Failing. |\n"); printk(KERN_INFO "joydump: | Cooked not available either. Failing. |\n");
printk(KERN_INFO "joydump: `-------------------- END -------------------'\n"); printk(KERN_INFO "joydump: `-------------------- END -------------------'\n");
return; return;
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -159,7 +159,7 @@ static void magellan_connect(struct serio *serio, struct serio_dev *dev) ...@@ -159,7 +159,7 @@ static void magellan_connect(struct serio *serio, struct serio_dev *dev)
memset(magellan, 0, sizeof(struct magellan)); memset(magellan, 0, sizeof(struct magellan));
magellan->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); magellan->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < 9; i++) for (i = 0; i < 9; i++)
set_bit(magellan_buttons[i], magellan->dev.keybit); set_bit(magellan_buttons[i], magellan->dev.keybit);
...@@ -181,7 +181,7 @@ static void magellan_connect(struct serio *serio, struct serio_dev *dev) ...@@ -181,7 +181,7 @@ static void magellan_connect(struct serio *serio, struct serio_dev *dev)
magellan->dev.id.vendor = SERIO_MAGELLAN; magellan->dev.id.vendor = SERIO_MAGELLAN;
magellan->dev.id.product = 0x0001; magellan->dev.id.product = 0x0001;
magellan->dev.id.version = 0x0100; magellan->dev.id.version = 0x0100;
serio->private = magellan; serio->private = magellan;
if (serio_open(serio, dev)) { if (serio_open(serio, dev)) {
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -176,19 +176,19 @@ static int sw_read_packet(struct gameport *gameport, unsigned char *buf, int len ...@@ -176,19 +176,19 @@ static int sw_read_packet(struct gameport *gameport, unsigned char *buf, int len
buf[i] = v >> 5; /* Store it */ buf[i] = v >> 5; /* Store it */
i++; /* Advance index */ i++; /* Advance index */
bitout = strobe; /* Extend timeout for next bit */ bitout = strobe; /* Extend timeout for next bit */
} }
if (kick && (~v & u & 0x01)) { /* Falling edge on axis 0 */ if (kick && (~v & u & 0x01)) { /* Falling edge on axis 0 */
sched = kick; /* Schedule second trigger */ sched = kick; /* Schedule second trigger */
kick = 0; /* Don't schedule next time on falling edge */ kick = 0; /* Don't schedule next time on falling edge */
pending = 1; /* Mark schedule */ pending = 1; /* Mark schedule */
} }
if (pending && sched < 0 && (i > -SW_END)) { /* Second trigger time */ if (pending && sched < 0 && (i > -SW_END)) { /* Second trigger time */
gameport_trigger(gameport); /* Trigger */ gameport_trigger(gameport); /* Trigger */
bitout = start; /* Long bit timeout */ bitout = start; /* Long bit timeout */
pending = 0; /* Unmark schedule */ pending = 0; /* Unmark schedule */
timeout = 0; /* Switch from global to bit timeouts */ timeout = 0; /* Switch from global to bit timeouts */
} }
} }
...@@ -482,14 +482,14 @@ static int sw_read(struct sw *sw) ...@@ -482,14 +482,14 @@ static int sw_read(struct sw *sw)
sw_read_packet(sw->gameport, buf, SW_LENGTH, i); /* Read ID packet, this initializes the stick */ sw_read_packet(sw->gameport, buf, SW_LENGTH, i); /* Read ID packet, this initializes the stick */
sw->fail = SW_FAIL; sw->fail = SW_FAIL;
return -1; return -1;
} }
static void sw_timer(unsigned long private) static void sw_timer(unsigned long private)
{ {
struct sw *sw = (void *) private; struct sw *sw = (void *) private;
sw->reads++; sw->reads++;
if (sw_read(sw)) sw->bads++; if (sw_read(sw)) sw->bads++;
mod_timer(&sw->timer, jiffies + SW_REFRESH); mod_timer(&sw->timer, jiffies + SW_REFRESH);
...@@ -653,7 +653,7 @@ static void sw_connect(struct gameport *gameport, struct gameport_dev *dev) ...@@ -653,7 +653,7 @@ static void sw_connect(struct gameport *gameport, struct gameport_dev *dev)
case 60: case 60:
sw->number++; sw->number++;
case 45: /* Ambiguous packet length */ case 45: /* Ambiguous packet length */
if (j <= 40) { /* ID length less or eq 40 -> FSP */ if (j <= 40) { /* ID length less or eq 40 -> FSP */
case 43: case 43:
sw->type = SW_ID_FSP; sw->type = SW_ID_FSP;
break; break;
......
...@@ -15,18 +15,18 @@ ...@@ -15,18 +15,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -59,8 +59,8 @@ MODULE_LICENSE("GPL"); ...@@ -59,8 +59,8 @@ MODULE_LICENSE("GPL");
static int spaceball_axes[] = { ABS_X, ABS_Z, ABS_Y, ABS_RX, ABS_RZ, ABS_RY }; static int spaceball_axes[] = { ABS_X, ABS_Z, ABS_Y, ABS_RX, ABS_RZ, ABS_RY };
static char *spaceball_names[] = { static char *spaceball_names[] = {
"?", "SpaceTec SpaceBall 1003", "SpaceTec SpaceBall 2003", "SpaceTec SpaceBall 2003B", "?", "SpaceTec SpaceBall 1003", "SpaceTec SpaceBall 2003", "SpaceTec SpaceBall 2003B",
"SpaceTec SpaceBall 2003C", "SpaceTec SpaceBall 3003", "SpaceTec SpaceBall SpaceController", "SpaceTec SpaceBall 2003C", "SpaceTec SpaceBall 3003", "SpaceTec SpaceBall SpaceController",
"SpaceTec SpaceBall 3003C", "SpaceTec SpaceBall 4000FLX", "SpaceTec SpaceBall 4000FLX Lefty" }; "SpaceTec SpaceBall 3003C", "SpaceTec SpaceBall 4000FLX", "SpaceTec SpaceBall 4000FLX Lefty" };
/* /*
...@@ -96,7 +96,7 @@ static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs ...@@ -96,7 +96,7 @@ static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs
case 'D': /* Ball data */ case 'D': /* Ball data */
if (spaceball->idx != 15) return; if (spaceball->idx != 15) return;
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
input_report_abs(dev, spaceball_axes[i], input_report_abs(dev, spaceball_axes[i],
(__s16)((data[2 * i + 3] << 8) | data[2 * i + 2])); (__s16)((data[2 * i + 3] << 8) | data[2 * i + 2]));
break; break;
...@@ -216,7 +216,7 @@ static void spaceball_connect(struct serio *serio, struct serio_dev *dev) ...@@ -216,7 +216,7 @@ static void spaceball_connect(struct serio *serio, struct serio_dev *dev)
return; return;
memset(spaceball, 0, sizeof(struct spaceball)); memset(spaceball, 0, sizeof(struct spaceball));
spaceball->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); spaceball->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
switch (id) { switch (id) {
case SPACEBALL_4000FLX: case SPACEBALL_4000FLX:
...@@ -224,7 +224,7 @@ static void spaceball_connect(struct serio *serio, struct serio_dev *dev) ...@@ -224,7 +224,7 @@ static void spaceball_connect(struct serio *serio, struct serio_dev *dev)
spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_9); spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_9);
spaceball->dev.keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE); spaceball->dev.keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
default: default:
spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
| BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8); | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8);
case SPACEBALL_3003C: case SPACEBALL_3003C:
spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8); spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
...@@ -251,7 +251,7 @@ static void spaceball_connect(struct serio *serio, struct serio_dev *dev) ...@@ -251,7 +251,7 @@ static void spaceball_connect(struct serio *serio, struct serio_dev *dev)
spaceball->dev.id.vendor = SERIO_SPACEBALL; spaceball->dev.id.vendor = SERIO_SPACEBALL;
spaceball->dev.id.product = id; spaceball->dev.id.product = id;
spaceball->dev.id.version = 0x0100; spaceball->dev.id.version = 0x0100;
serio->private = spaceball; serio->private = spaceball;
if (serio_open(serio, dev)) { if (serio_open(serio, dev)) {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* $Id: spaceorb.c,v 1.15 2002/01/22 20:29:19 vojtech Exp $ * $Id: spaceorb.c,v 1.15 2002/01/22 20:29:19 vojtech Exp $
* *
* Copyright (c) 1999-2001 Vojtech Pavlik * Copyright (c) 1999-2001 Vojtech Pavlik
* *
* Based on the work of: * Based on the work of:
* David Thompson * David Thompson
*/ */
...@@ -14,18 +14,18 @@ ...@@ -14,18 +14,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -67,7 +67,7 @@ struct spaceorb { ...@@ -67,7 +67,7 @@ struct spaceorb {
static unsigned char spaceorb_xor[] = "SpaceWare"; static unsigned char spaceorb_xor[] = "SpaceWare";
static unsigned char *spaceorb_errors[] = { "EEPROM storing 0 failed", "Receive queue overflow", "Transmit queue timeout", static unsigned char *spaceorb_errors[] = { "EEPROM storing 0 failed", "Receive queue overflow", "Transmit queue timeout",
"Bad packet", "Power brown-out", "EEPROM checksum error", "Hardware fault" }; "Bad packet", "Power brown-out", "EEPROM checksum error", "Hardware fault" };
/* /*
* spaceorb_process_packet() decodes packets the driver receives from the * spaceorb_process_packet() decodes packets the driver receives from the
...@@ -99,7 +99,7 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r ...@@ -99,7 +99,7 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r
case 'D': /* Ball + button data */ case 'D': /* Ball + button data */
if (spaceorb->idx != 12) return; if (spaceorb->idx != 12) return;
for (i = 0; i < 9; i++) spaceorb->data[i+2] ^= spaceorb_xor[i]; for (i = 0; i < 9; i++) spaceorb->data[i+2] ^= spaceorb_xor[i];
axes[0] = ( data[2] << 3) | (data[ 3] >> 4); axes[0] = ( data[2] << 3) | (data[ 3] >> 4);
axes[1] = ((data[3] & 0x0f) << 6) | (data[ 4] >> 1); axes[1] = ((data[3] & 0x0f) << 6) | (data[ 4] >> 1);
axes[2] = ((data[4] & 0x01) << 9) | (data[ 5] << 2) | (data[4] >> 5); axes[2] = ((data[4] & 0x01) << 9) | (data[ 5] << 2) | (data[4] >> 5);
...@@ -174,7 +174,7 @@ static void spaceorb_connect(struct serio *serio, struct serio_dev *dev) ...@@ -174,7 +174,7 @@ static void spaceorb_connect(struct serio *serio, struct serio_dev *dev)
return; return;
memset(spaceorb, 0, sizeof(struct spaceorb)); memset(spaceorb, 0, sizeof(struct spaceorb));
spaceorb->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); spaceorb->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
set_bit(spaceorb_buttons[i], spaceorb->dev.keybit); set_bit(spaceorb_buttons[i], spaceorb->dev.keybit);
...@@ -198,7 +198,7 @@ static void spaceorb_connect(struct serio *serio, struct serio_dev *dev) ...@@ -198,7 +198,7 @@ static void spaceorb_connect(struct serio *serio, struct serio_dev *dev)
spaceorb->dev.id.vendor = SERIO_SPACEORB; spaceorb->dev.id.vendor = SERIO_SPACEORB;
spaceorb->dev.id.product = 0x0001; spaceorb->dev.id.product = 0x0001;
spaceorb->dev.id.version = 0x0100; spaceorb->dev.id.version = 0x0100;
serio->private = spaceorb; serio->private = spaceorb;
if (serio_open(serio, dev)) { if (serio_open(serio, dev)) {
......
...@@ -147,7 +147,7 @@ static void stinger_connect(struct serio *serio, struct serio_dev *dev) ...@@ -147,7 +147,7 @@ static void stinger_connect(struct serio *serio, struct serio_dev *dev)
memset(stinger, 0, sizeof(struct stinger)); memset(stinger, 0, sizeof(struct stinger));
stinger->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); stinger->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
stinger->dev.keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | \ stinger->dev.keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | \
BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) | \ BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) | \
BIT(BTN_START) | BIT(BTN_SELECT); BIT(BTN_START) | BIT(BTN_SELECT);
...@@ -164,8 +164,8 @@ static void stinger_connect(struct serio *serio, struct serio_dev *dev) ...@@ -164,8 +164,8 @@ static void stinger_connect(struct serio *serio, struct serio_dev *dev)
stinger->dev.id.version = 0x0100; stinger->dev.id.version = 0x0100;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
stinger->dev.absmax[ABS_X+i] = 64; stinger->dev.absmax[ABS_X+i] = 64;
stinger->dev.absmin[ABS_X+i] = -64; stinger->dev.absmin[ABS_X+i] = -64;
stinger->dev.absflat[ABS_X+i] = 4; stinger->dev.absflat[ABS_X+i] = 4;
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Copyright (c) 1998-2001 Vojtech Pavlik * Copyright (c) 1998-2001 Vojtech Pavlik
* *
* Based on the work of: * Based on the work of:
* Trystan Larey-Williams * Trystan Larey-Williams
*/ */
/* /*
...@@ -14,18 +14,18 @@ ...@@ -14,18 +14,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -58,7 +58,7 @@ MODULE_LICENSE("GPL"); ...@@ -58,7 +58,7 @@ MODULE_LICENSE("GPL");
#define TMDC_BYTE_REV 11 #define TMDC_BYTE_REV 11
#define TMDC_BYTE_DEF 12 #define TMDC_BYTE_DEF 12
#define TMDC_ABS 7 #define TMDC_ABS 7
#define TMDC_ABS_HAT 4 #define TMDC_ABS_HAT 4
#define TMDC_BTN 16 #define TMDC_BTN 16
...@@ -104,7 +104,7 @@ struct tmdc { ...@@ -104,7 +104,7 @@ struct tmdc {
unsigned char btno[2][4]; unsigned char btno[2][4];
int used; int used;
int reads; int reads;
int bads; int bads;
unsigned char exists; unsigned char exists;
}; };
...@@ -127,7 +127,7 @@ static int tmdc_read_packet(struct gameport *gameport, unsigned char data[2][TMD ...@@ -127,7 +127,7 @@ static int tmdc_read_packet(struct gameport *gameport, unsigned char data[2][TMD
local_irq_save(flags); local_irq_save(flags);
gameport_trigger(gameport); gameport_trigger(gameport);
w = gameport_read(gameport) >> 4; w = gameport_read(gameport) >> 4;
do { do {
...@@ -148,7 +148,7 @@ static int tmdc_read_packet(struct gameport *gameport, unsigned char data[2][TMD ...@@ -148,7 +148,7 @@ static int tmdc_read_packet(struct gameport *gameport, unsigned char data[2][TMD
} }
data[k][i[k]] |= (~v & 1) << (j[k]++ - 1); /* Data bit */ data[k][i[k]] |= (~v & 1) << (j[k]++ - 1); /* Data bit */
} }
t[k]--; t[k]--;
} }
} while (t[0] > 0 || t[1] > 0); } while (t[0] > 0 || t[1] > 0);
...@@ -175,7 +175,7 @@ static void tmdc_timer(unsigned long private) ...@@ -175,7 +175,7 @@ static void tmdc_timer(unsigned long private)
bad = 1; bad = 1;
else else
for (j = 0; j < 2; j++) for (j = 0; j < 2; j++)
if (r & (1 << j) & tmdc->exists) { if (r & (1 << j) & tmdc->exists) {
if (data[j][TMDC_BYTE_ID] != tmdc->mode[j]) { if (data[j][TMDC_BYTE_ID] != tmdc->mode[j]) {
...@@ -227,7 +227,7 @@ static int tmdc_open(struct input_dev *dev) ...@@ -227,7 +227,7 @@ static int tmdc_open(struct input_dev *dev)
{ {
struct tmdc *tmdc = dev->private; struct tmdc *tmdc = dev->private;
if (!tmdc->used++) if (!tmdc->used++)
mod_timer(&tmdc->timer, jiffies + TMDC_REFRESH_TIME); mod_timer(&tmdc->timer, jiffies + TMDC_REFRESH_TIME);
return 0; return 0;
} }
...@@ -356,7 +356,7 @@ static void tmdc_disconnect(struct gameport *gameport) ...@@ -356,7 +356,7 @@ static void tmdc_disconnect(struct gameport *gameport)
struct tmdc *tmdc = gameport->private; struct tmdc *tmdc = gameport->private;
int i; int i;
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
if (tmdc->exists & (1 << i)) if (tmdc->exists & (1 << i))
input_unregister_device(tmdc->dev + i); input_unregister_device(tmdc->dev + i);
gameport_close(gameport); gameport_close(gameport);
kfree(tmdc); kfree(tmdc);
......
...@@ -14,18 +14,18 @@ ...@@ -14,18 +14,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -65,7 +65,7 @@ __obsolete_setup("tgfx_3="); ...@@ -65,7 +65,7 @@ __obsolete_setup("tgfx_3=");
#define TGFX_TRIGGER 0x08 #define TGFX_TRIGGER 0x08
#define TGFX_UP 0x10 #define TGFX_UP 0x10
#define TGFX_DOWN 0x20 #define TGFX_DOWN 0x20
#define TGFX_LEFT 0x40 #define TGFX_LEFT 0x40
#define TGFX_RIGHT 0x80 #define TGFX_RIGHT 0x80
...@@ -126,7 +126,7 @@ static int tgfx_open(struct input_dev *dev) ...@@ -126,7 +126,7 @@ static int tgfx_open(struct input_dev *dev)
if (!tgfx->used++) { if (!tgfx->used++) {
parport_claim(tgfx->pd); parport_claim(tgfx->pd);
parport_write_control(tgfx->pd->port, 0x04); parport_write_control(tgfx->pd->port, 0x04);
mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME); mod_timer(&tgfx->timer, jiffies + TGFX_REFRESH_TIME);
} }
return 0; return 0;
} }
...@@ -173,7 +173,7 @@ static struct tgfx __init *tgfx_probe(int *config, int nargs) ...@@ -173,7 +173,7 @@ static struct tgfx __init *tgfx_probe(int *config, int nargs)
memset(tgfx, 0, sizeof(struct tgfx)); memset(tgfx, 0, sizeof(struct tgfx));
tgfx->pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); tgfx->pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
parport_put_port(pp); parport_put_port(pp);
if (!tgfx->pd) { if (!tgfx->pd) {
...@@ -210,7 +210,7 @@ static struct tgfx __init *tgfx_probe(int *config, int nargs) ...@@ -210,7 +210,7 @@ static struct tgfx __init *tgfx_probe(int *config, int nargs)
tgfx->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y); tgfx->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
for (j = 0; j < config[i+1]; j++) for (j = 0; j < config[i+1]; j++)
set_bit(tgfx_buttons[j], tgfx->dev[i].keybit); set_bit(tgfx_buttons[j], tgfx->dev[i].keybit);
tgfx->dev[i].absmin[ABS_X] = -1; tgfx->dev[i].absmax[ABS_X] = 1; tgfx->dev[i].absmin[ABS_X] = -1; tgfx->dev[i].absmax[ABS_X] = 1;
tgfx->dev[i].absmin[ABS_Y] = -1; tgfx->dev[i].absmax[ABS_Y] = 1; tgfx->dev[i].absmin[ABS_Y] = -1; tgfx->dev[i].absmax[ABS_Y] = 1;
...@@ -225,7 +225,7 @@ static struct tgfx __init *tgfx_probe(int *config, int nargs) ...@@ -225,7 +225,7 @@ static struct tgfx __init *tgfx_probe(int *config, int nargs)
kfree(tgfx); kfree(tgfx);
return NULL; return NULL;
} }
return tgfx; return tgfx;
} }
...@@ -245,7 +245,7 @@ void __exit tgfx_exit(void) ...@@ -245,7 +245,7 @@ void __exit tgfx_exit(void)
{ {
int i, j; int i, j;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
if (tgfx_base[i]) { if (tgfx_base[i]) {
for (j = 0; j < 7; j++) for (j = 0; j < 7; j++)
if (tgfx_base[i]->sticks & (1 << j)) if (tgfx_base[i]->sticks & (1 << j))
......
...@@ -58,6 +58,9 @@ ...@@ -58,6 +58,9 @@
#include <linux/serio.h> #include <linux/serio.h>
#include <linux/init.h> #include <linux/init.h>
MODULE_DESCRIPTION("Handykey Twiddler keyboard as a joystick driver");
MODULE_LICENSE("GPL");
/* /*
* Constants. * Constants.
*/ */
...@@ -142,7 +145,7 @@ static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs ...@@ -142,7 +145,7 @@ static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs
* packet processing routine. * packet processing routine.
*/ */
static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struc pt_regs *regs) static irqreturn_t twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
{ {
struct twidjoy *twidjoy = serio->private; struct twidjoy *twidjoy = serio->private;
...@@ -153,7 +156,7 @@ static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned ...@@ -153,7 +156,7 @@ static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned
if ((data & 0x80) == 0) if ((data & 0x80) == 0)
twidjoy->idx = 0; /* this byte starts a new packet */ twidjoy->idx = 0; /* this byte starts a new packet */
else if (twidjoy->idx == 0) else if (twidjoy->idx == 0)
return; /* wrong MSB -- ignore this byte */ return IRQ_HANDLED; /* wrong MSB -- ignore this byte */
if (twidjoy->idx < TWIDJOY_MAX_LENGTH) if (twidjoy->idx < TWIDJOY_MAX_LENGTH)
twidjoy->data[twidjoy->idx++] = data; twidjoy->data[twidjoy->idx++] = data;
...@@ -163,7 +166,7 @@ static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned ...@@ -163,7 +166,7 @@ static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned
twidjoy->idx = 0; twidjoy->idx = 0;
} }
return; return IRQ_HANDLED;
} }
/* /*
...@@ -208,7 +211,7 @@ static void twidjoy_connect(struct serio *serio, struct serio_dev *dev) ...@@ -208,7 +211,7 @@ static void twidjoy_connect(struct serio *serio, struct serio_dev *dev)
twidjoy->dev.id.product = 0x0001; twidjoy->dev.id.product = 0x0001;
twidjoy->dev.id.version = 0x0100; twidjoy->dev.id.version = 0x0100;
twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
for (bp = twidjoy_buttons; bp->bitmask; bp++) { for (bp = twidjoy_buttons; bp->bitmask; bp++) {
for (i = 0; i < bp->bitmask; i++) for (i = 0; i < bp->bitmask; i++)
...@@ -218,8 +221,8 @@ static void twidjoy_connect(struct serio *serio, struct serio_dev *dev) ...@@ -218,8 +221,8 @@ static void twidjoy_connect(struct serio *serio, struct serio_dev *dev)
twidjoy->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); twidjoy->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
twidjoy->dev.absmax[ABS_X+i] = 50; twidjoy->dev.absmax[ABS_X+i] = 50;
twidjoy->dev.absmin[ABS_X+i] = -50; twidjoy->dev.absmin[ABS_X+i] = -50;
/* TODO: arndt 20010708: Are these values appropriate? */ /* TODO: arndt 20010708: Are these values appropriate? */
twidjoy->dev.absfuzz[ABS_X+i] = 4; twidjoy->dev.absfuzz[ABS_X+i] = 4;
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
/* /*
* This program is free warftware; you can redistribute it and/or modify * This program is free warftware; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -44,7 +44,7 @@ MODULE_LICENSE("GPL"); ...@@ -44,7 +44,7 @@ MODULE_LICENSE("GPL");
*/ */
#define WARRIOR_MAX_LENGTH 16 #define WARRIOR_MAX_LENGTH 16
static char warrior_lengths[] = { 0, 4, 12, 3, 4, 4, 0, 0 }; static char warrior_lengths[] = { 0, 4, 12, 3, 4, 4, 0, 0 };
static char *warrior_name = "Logitech WingMan Warrior"; static char *warrior_name = "Logitech WingMan Warrior";
/* /*
...@@ -114,7 +114,7 @@ static irqreturn_t warrior_interrupt(struct serio *serio, ...@@ -114,7 +114,7 @@ static irqreturn_t warrior_interrupt(struct serio *serio,
warrior->data[warrior->idx++] = data; warrior->data[warrior->idx++] = data;
if (warrior->idx == warrior->len) { if (warrior->idx == warrior->len) {
if (warrior->idx) warrior_process_packet(warrior, regs); if (warrior->idx) warrior_process_packet(warrior, regs);
warrior->idx = 0; warrior->idx = 0;
warrior->len = 0; warrior->len = 0;
} }
...@@ -152,7 +152,7 @@ static void warrior_connect(struct serio *serio, struct serio_dev *dev) ...@@ -152,7 +152,7 @@ static void warrior_connect(struct serio *serio, struct serio_dev *dev)
memset(warrior, 0, sizeof(struct warrior)); memset(warrior, 0, sizeof(struct warrior));
warrior->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); warrior->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
warrior->dev.keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2); warrior->dev.keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2);
warrior->dev.relbit[0] = BIT(REL_DIAL); warrior->dev.relbit[0] = BIT(REL_DIAL);
warrior->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y); warrior->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y);
...@@ -168,24 +168,24 @@ static void warrior_connect(struct serio *serio, struct serio_dev *dev) ...@@ -168,24 +168,24 @@ static void warrior_connect(struct serio *serio, struct serio_dev *dev)
warrior->dev.id.version = 0x0100; warrior->dev.id.version = 0x0100;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
warrior->dev.absmax[ABS_X+i] = -64; warrior->dev.absmax[ABS_X+i] = -64;
warrior->dev.absmin[ABS_X+i] = 64; warrior->dev.absmin[ABS_X+i] = 64;
warrior->dev.absflat[ABS_X+i] = 8; warrior->dev.absflat[ABS_X+i] = 8;
} }
warrior->dev.absmax[ABS_THROTTLE] = -112; warrior->dev.absmax[ABS_THROTTLE] = -112;
warrior->dev.absmin[ABS_THROTTLE] = 112; warrior->dev.absmin[ABS_THROTTLE] = 112;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
warrior->dev.absmax[ABS_HAT0X+i] = -1; warrior->dev.absmax[ABS_HAT0X+i] = -1;
warrior->dev.absmin[ABS_HAT0X+i] = 1; warrior->dev.absmin[ABS_HAT0X+i] = 1;
} }
warrior->dev.private = warrior; warrior->dev.private = warrior;
serio->private = warrior; serio->private = warrior;
if (serio_open(serio, dev)) { if (serio_open(serio, dev)) {
kfree(warrior); kfree(warrior);
return; return;
} }
......
...@@ -12,18 +12,18 @@ ...@@ -12,18 +12,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
*/ */
#include <linux/delay.h> #include <linux/delay.h>
...@@ -43,7 +43,7 @@ MODULE_LICENSE("GPL"); ...@@ -43,7 +43,7 @@ MODULE_LICENSE("GPL");
#define KBD98_KEY 0x7f #define KBD98_KEY 0x7f
#define KBD98_RELEASE 0x80 #define KBD98_RELEASE 0x80
static unsigned char kbd98_keycode[256] = { static unsigned char kbd98_keycode[256] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 43, 14, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 43, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 41, 26, 28, 30, 31, 32, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 41, 26, 28, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40, 27, 44, 45, 46, 47, 48, 49, 50, 33, 34, 35, 36, 37, 38, 39, 40, 27, 44, 45, 46, 47, 48, 49, 50,
...@@ -109,8 +109,8 @@ struct kbd98 { ...@@ -109,8 +109,8 @@ struct kbd98 {
struct jis_kbd_conv jis[16]; struct jis_kbd_conv jis[16];
}; };
void kbd98_interrupt(struct serio *serio, unsigned char data, irqreturn_t kbd98_interrupt(struct serio *serio, unsigned char data,
unsigned int flags, struct pt_regs *regs) unsigned int flags, struct pt_regs *regs)
{ {
struct kbd98 *kbd98 = serio->private; struct kbd98 *kbd98 = serio->private;
unsigned char scancode, keycode; unsigned char scancode, keycode;
...@@ -119,15 +119,15 @@ void kbd98_interrupt(struct serio *serio, unsigned char data, ...@@ -119,15 +119,15 @@ void kbd98_interrupt(struct serio *serio, unsigned char data,
switch (data) { switch (data) {
case KBD98_RET_ACK: case KBD98_RET_ACK:
kbd98->ack = 1; kbd98->ack = 1;
return; goto out;
case KBD98_RET_NAK: case KBD98_RET_NAK:
kbd98->ack = -1; kbd98->ack = -1;
return; goto out;
} }
if (kbd98->cmdcnt) { if (kbd98->cmdcnt) {
kbd98->cmdbuf[--kbd98->cmdcnt] = data; kbd98->cmdbuf[--kbd98->cmdcnt] = data;
return; goto out;
} }
scancode = data & KBD98_KEY; scancode = data & KBD98_KEY;
...@@ -164,7 +164,7 @@ void kbd98_interrupt(struct serio *serio, unsigned char data, ...@@ -164,7 +164,7 @@ void kbd98_interrupt(struct serio *serio, unsigned char data,
keycode = kbd98->jis[i].emul[kbd98->shift].keycode; keycode = kbd98->jis[i].emul[kbd98->shift].keycode;
if (keycode == KBD98_KEY_NULL) if (keycode == KBD98_KEY_NULL)
return; break;
if (press) { if (press) {
kbd98->emul.scancode = scancode; kbd98->emul.scancode = scancode;
...@@ -187,27 +187,31 @@ void kbd98_interrupt(struct serio *serio, unsigned char data, ...@@ -187,27 +187,31 @@ void kbd98_interrupt(struct serio *serio, unsigned char data,
} }
input_sync(&kbd98->dev); input_sync(&kbd98->dev);
return; break;
case KEY_CAPSLOCK: case KEY_CAPSLOCK:
input_report_key(&kbd98->dev, keycode, 1); input_report_key(&kbd98->dev, keycode, 1);
input_sync(&kbd98->dev); input_sync(&kbd98->dev);
input_report_key(&kbd98->dev, keycode, 0); input_report_key(&kbd98->dev, keycode, 0);
input_sync(&kbd98->dev); input_sync(&kbd98->dev);
return; break;
case KBD98_KEY_NULL: case KBD98_KEY_NULL:
return; break;
case 0: case 0:
printk(KERN_WARNING "kbd98.c: Unknown key (scancode %#x) %s.\n", printk(KERN_WARNING "kbd98.c: Unknown key (scancode %#x) %s.\n",
data & KBD98_KEY, data & KBD98_RELEASE ? "released" : "pressed"); data & KBD98_KEY, data & KBD98_RELEASE ? "released" : "pressed");
return; break;
default: default:
input_report_key(&kbd98->dev, keycode, press); input_report_key(&kbd98->dev, keycode, press);
input_sync(&kbd98->dev); input_sync(&kbd98->dev);
} break;
}
out:
return IRQ_HANDLED;
} }
/* /*
...@@ -243,7 +247,7 @@ static int kbd98_command(struct kbd98 *kbd98, unsigned char *param, int command) ...@@ -243,7 +247,7 @@ static int kbd98_command(struct kbd98 *kbd98, unsigned char *param, int command)
int i; int i;
kbd98->cmdcnt = receive; kbd98->cmdcnt = receive;
if (command & 0xff) if (command & 0xff)
if (kbd98_sendbyte(kbd98, command & 0xff)) if (kbd98_sendbyte(kbd98, command & 0xff))
return (kbd98->cmdcnt = 0) - 1; return (kbd98->cmdcnt = 0) - 1;
...@@ -258,7 +262,7 @@ static int kbd98_command(struct kbd98 *kbd98, unsigned char *param, int command) ...@@ -258,7 +262,7 @@ static int kbd98_command(struct kbd98 *kbd98, unsigned char *param, int command)
for (i = 0; i < receive; i++) for (i = 0; i < receive; i++)
param[i] = kbd98->cmdbuf[(receive - 1) - i]; param[i] = kbd98->cmdbuf[(receive - 1) - i];
if (kbd98->cmdcnt) if (kbd98->cmdcnt)
return (kbd98->cmdcnt = 0) - 1; return (kbd98->cmdcnt = 0) - 1;
return 0; return 0;
...@@ -318,7 +322,7 @@ void kbd98_connect(struct serio *serio, struct serio_dev *dev) ...@@ -318,7 +322,7 @@ void kbd98_connect(struct serio *serio, struct serio_dev *dev)
memset(kbd98, 0, sizeof(struct kbd98)); memset(kbd98, 0, sizeof(struct kbd98));
kbd98->emul.scancode = KBD98_KEY_UNKNOWN; kbd98->emul.scancode = KBD98_KEY_UNKNOWN;
kbd98->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); kbd98->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
kbd98->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_KANA); kbd98->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_KANA);
......
...@@ -62,7 +62,7 @@ config KEYBOARD_XTKBD ...@@ -62,7 +62,7 @@ config KEYBOARD_XTKBD
Say Y here if you want to use the old IBM PC/XT keyboard (or Say Y here if you want to use the old IBM PC/XT keyboard (or
compatible) on your system. This is only possible with a compatible) on your system. This is only possible with a
parallel port keyboard adapter, you cannot connect it to the parallel port keyboard adapter, you cannot connect it to the
keyboard port on a PC that runs Linux. keyboard port on a PC that runs Linux.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called xtkbd. module will be called xtkbd.
...@@ -92,7 +92,7 @@ config KEYBOARD_AMIGA ...@@ -92,7 +92,7 @@ config KEYBOARD_AMIGA
depends on AMIGA && INPUT && INPUT_KEYBOARD depends on AMIGA && INPUT && INPUT_KEYBOARD
help help
Say Y here if you are running Linux on any AMIGA and have a keyboard Say Y here if you are running Linux on any AMIGA and have a keyboard
attached. attached.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called amikbd. module will be called amikbd.
...@@ -103,7 +103,7 @@ config KEYBOARD_98KBD ...@@ -103,7 +103,7 @@ config KEYBOARD_98KBD
select SERIO select SERIO
help help
Say Y here if you want to use the NEC PC-9801/PC-9821 keyboard (or Say Y here if you want to use the NEC PC-9801/PC-9821 keyboard (or
compatible) on your system. compatible) on your system.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called 98kbd. module will be called 98kbd.
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include <linux/input.h> #include <linux/input.h>
#include <linux/serio.h> #include <linux/serio.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/timer.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_DESCRIPTION("AT and PS/2 keyboard driver"); MODULE_DESCRIPTION("AT and PS/2 keyboard driver");
...@@ -173,22 +172,24 @@ struct atkbd { ...@@ -173,22 +172,24 @@ struct atkbd {
unsigned char keycode[512]; unsigned char keycode[512];
struct input_dev dev; struct input_dev dev;
struct serio *serio; struct serio *serio;
struct timer_list timer;
char name[64]; char name[64];
char phys[32]; char phys[32];
unsigned short id;
unsigned char set;
unsigned int translated:1;
unsigned int extra:1;
unsigned int write:1;
unsigned char cmdbuf[4]; unsigned char cmdbuf[4];
unsigned char cmdcnt; unsigned char cmdcnt;
unsigned char set;
unsigned char extra;
unsigned char release;
int lastkey;
volatile signed char ack; volatile signed char ack;
unsigned char emul; unsigned char emul;
unsigned short id; unsigned int resend:1;
unsigned char write; unsigned int release:1;
unsigned char translated; unsigned int bat_xl:1;
unsigned char resend; unsigned int enabled:1;
unsigned char bat_xl;
unsigned int last; unsigned int last;
unsigned long time; unsigned long time;
}; };
...@@ -248,6 +249,9 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -248,6 +249,9 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
goto out; goto out;
} }
if (!atkbd->enabled)
goto out;
if (atkbd->translated) { if (atkbd->translated) {
if (atkbd->emul || if (atkbd->emul ||
...@@ -300,15 +304,20 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, ...@@ -300,15 +304,20 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
case ATKBD_KEY_NULL: case ATKBD_KEY_NULL:
break; break;
case ATKBD_KEY_UNKNOWN: case ATKBD_KEY_UNKNOWN:
printk(KERN_WARNING "atkbd.c: Unknown key %s (%s set %d, code %#x on %s).\n", if (data == ATKBD_RET_ACK || data == ATKBD_RET_NAK) {
atkbd->release ? "released" : "pressed", printk(KERN_WARNING "atkbd.c: Spurious %s on %s. Some program, "
atkbd->translated ? "translated" : "raw", "like XFree86, might be trying access hardware directly.\n",
atkbd->set, code, serio->phys); data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
if (atkbd->translated && atkbd->set == 2 && code == 0x7a) } else {
printk(KERN_WARNING "atkbd.c: This is an XFree86 bug. It shouldn't access" printk(KERN_WARNING "atkbd.c: Unknown key %s "
" hardware directly.\n"); "(%s set %d, code %#x on %s).\n",
else atkbd->release ? "released" : "pressed",
printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x <keycode>' to make it known.\n", code & 0x80 ? "e0" : "", code & 0x7f); atkbd->translated ? "translated" : "raw",
atkbd->set, code, serio->phys);
printk(KERN_WARNING "atkbd.c: Use 'setkeycodes %s%02x <keycode>' "
"to make it known.\n",
code & 0x80 ? "e0" : "", code & 0x7f);
}
break; break;
case ATKBD_SCR_1: case ATKBD_SCR_1:
scroll = 1 - atkbd->release * 2; scroll = 1 - atkbd->release * 2;
...@@ -745,6 +754,8 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev) ...@@ -745,6 +754,8 @@ static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
atkbd->id = 0xab00; atkbd->id = 0xab00;
} }
atkbd->enabled = 1;
if (atkbd->extra) { if (atkbd->extra) {
atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC); atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
sprintf(atkbd->name, "AT Set 2 Extra keyboard"); sprintf(atkbd->name, "AT Set 2 Extra keyboard");
...@@ -809,12 +820,12 @@ static int atkbd_reconnect(struct serio *serio) ...@@ -809,12 +820,12 @@ static int atkbd_reconnect(struct serio *serio)
param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0) param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0)
| (test_bit(LED_NUML, atkbd->dev.led) ? 2 : 0) | (test_bit(LED_NUML, atkbd->dev.led) ? 2 : 0)
| (test_bit(LED_CAPSL, atkbd->dev.led) ? 4 : 0); | (test_bit(LED_CAPSL, atkbd->dev.led) ? 4 : 0);
if (atkbd_probe(atkbd)) if (atkbd_probe(atkbd))
return -1; return -1;
if (atkbd->set != atkbd_set_3(atkbd)) if (atkbd->set != atkbd_set_3(atkbd))
return -1; return -1;
atkbd_enable(atkbd); atkbd_enable(atkbd);
if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS)) if (atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS))
......
...@@ -139,7 +139,7 @@ static int dc_kbd_connect(struct maple_device *dev) ...@@ -139,7 +139,7 @@ static int dc_kbd_connect(struct maple_device *dev)
kbd->dev.name = dev->product_name; kbd->dev.name = dev->product_name;
kbd->dev.id.bustype = BUS_MAPLE; kbd->dev.id.bustype = BUS_MAPLE;
input_register_device(&kbd->dev); input_register_device(&kbd->dev);
maple_getcond_callback(dev, dc_kbd_callback, 1, MAPLE_FUNC_KEYBOARD); maple_getcond_callback(dev, dc_kbd_callback, 1, MAPLE_FUNC_KEYBOARD);
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -148,7 +148,7 @@ static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int c ...@@ -148,7 +148,7 @@ static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int c
case EV_LED: case EV_LED:
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED); sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
sunkbd->serio->write(sunkbd->serio, sunkbd->serio->write(sunkbd->serio,
(!!test_bit(LED_CAPSL, dev->led) << 3) | (!!test_bit(LED_SCROLLL, dev->led) << 2) | (!!test_bit(LED_CAPSL, dev->led) << 3) | (!!test_bit(LED_SCROLLL, dev->led) << 2) |
(!!test_bit(LED_COMPOSE, dev->led) << 1) | !!test_bit(LED_NUML, dev->led)); (!!test_bit(LED_COMPOSE, dev->led) << 1) | !!test_bit(LED_NUML, dev->led));
return 0; return 0;
...@@ -160,7 +160,7 @@ static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int c ...@@ -160,7 +160,7 @@ static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int c
case SND_CLICK: case SND_CLICK:
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - value); sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - value);
return 0; return 0;
case SND_BELL: case SND_BELL:
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - value); sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - value);
return 0; return 0;
...@@ -210,7 +210,7 @@ static void sunkbd_reinit(void *data) ...@@ -210,7 +210,7 @@ static void sunkbd_reinit(void *data)
wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ); wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED); sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
sunkbd->serio->write(sunkbd->serio, sunkbd->serio->write(sunkbd->serio,
(!!test_bit(LED_CAPSL, sunkbd->dev.led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev.led) << 2) | (!!test_bit(LED_CAPSL, sunkbd->dev.led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev.led) << 2) |
(!!test_bit(LED_COMPOSE, sunkbd->dev.led) << 1) | !!test_bit(LED_NUML, sunkbd->dev.led)); (!!test_bit(LED_COMPOSE, sunkbd->dev.led) << 1) | !!test_bit(LED_NUML, sunkbd->dev.led));
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev.snd)); sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev.snd));
...@@ -231,7 +231,7 @@ static void sunkbd_connect(struct serio *serio, struct serio_dev *dev) ...@@ -231,7 +231,7 @@ static void sunkbd_connect(struct serio *serio, struct serio_dev *dev)
if ((serio->type & SERIO_PROTO) && (serio->type & SERIO_PROTO) != SERIO_SUNKBD) if ((serio->type & SERIO_PROTO) && (serio->type & SERIO_PROTO) != SERIO_SUNKBD)
return; return;
if (!(sunkbd = kmalloc(sizeof(struct sunkbd), GFP_KERNEL))) if (!(sunkbd = kmalloc(sizeof(struct sunkbd), GFP_KERNEL)))
return; return;
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -43,7 +43,7 @@ MODULE_LICENSE("GPL"); ...@@ -43,7 +43,7 @@ MODULE_LICENSE("GPL");
#define XTKBD_KEY 0x7f #define XTKBD_KEY 0x7f
#define XTKBD_RELEASE 0x80 #define XTKBD_RELEASE 0x80
static unsigned char xtkbd_keycode[256] = { static unsigned char xtkbd_keycode[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
...@@ -98,7 +98,7 @@ void xtkbd_connect(struct serio *serio, struct serio_dev *dev) ...@@ -98,7 +98,7 @@ void xtkbd_connect(struct serio *serio, struct serio_dev *dev)
return; return;
memset(xtkbd, 0, sizeof(struct xtkbd)); memset(xtkbd, 0, sizeof(struct xtkbd));
xtkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); xtkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
xtkbd->serio = serio; xtkbd->serio = serio;
......
...@@ -42,11 +42,11 @@ static int spkr98_event(struct input_dev *dev, unsigned int type, unsigned int c ...@@ -42,11 +42,11 @@ static int spkr98_event(struct input_dev *dev, unsigned int type, unsigned int c
case SND_BELL: if (value) value = 1000; case SND_BELL: if (value) value = 1000;
case SND_TONE: break; case SND_TONE: break;
default: return -1; default: return -1;
} }
if (value > 20 && value < 32767) if (value > 20 && value < 32767)
count = PIT_TICK_RATE / value; count = PIT_TICK_RATE / value;
spin_lock_irqsave(&i8253_beep_lock, flags); spin_lock_irqsave(&i8253_beep_lock, flags);
if (count) { if (count) {
......
...@@ -41,11 +41,11 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c ...@@ -41,11 +41,11 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c
case SND_BELL: if (value) value = 1000; case SND_BELL: if (value) value = 1000;
case SND_TONE: break; case SND_TONE: break;
default: return -1; default: return -1;
} }
if (value > 20 && value < 32767) if (value > 20 && value < 32767)
count = PIT_TICK_RATE / value; count = PIT_TICK_RATE / value;
spin_lock_irqsave(&i8253_beep_lock, flags); spin_lock_irqsave(&i8253_beep_lock, flags);
if (count) { if (count) {
......
...@@ -53,11 +53,11 @@ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned in ...@@ -53,11 +53,11 @@ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned in
case SND_BELL: if (value) value = 1000; case SND_BELL: if (value) value = 1000;
case SND_TONE: break; case SND_TONE: break;
default: return -1; default: return -1;
} }
if (value > 20 && value < 32767) if (value > 20 && value < 32767)
count = 1193182 / value; count = 1193182 / value;
spin_lock_irqsave(&beep_lock, flags); spin_lock_irqsave(&beep_lock, flags);
/* EBUS speaker only has on/off state, the frequency does not /* EBUS speaker only has on/off state, the frequency does not
...@@ -108,11 +108,11 @@ static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int ...@@ -108,11 +108,11 @@ static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int
case SND_BELL: if (value) value = 1000; case SND_BELL: if (value) value = 1000;
case SND_TONE: break; case SND_TONE: break;
default: return -1; default: return -1;
} }
if (value > 20 && value < 32767) if (value > 20 && value < 32767)
count = 1193182 / value; count = 1193182 / value;
spin_lock_irqsave(&beep_lock, flags); spin_lock_irqsave(&beep_lock, flags);
if (count) { if (count) {
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org> * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
* *
* Changes/Revisions: * Changes/Revisions:
* 0.1 20/06/2002 * 0.1 20/06/2002
* - first public version * - first public version
...@@ -68,7 +68,7 @@ static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *eff ...@@ -68,7 +68,7 @@ static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *eff
static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
{ {
return 0; return 0;
} }
static int uinput_create_device(struct uinput_device *udev) static int uinput_create_device(struct uinput_device *udev)
{ {
...@@ -123,7 +123,7 @@ static int uinput_open(struct inode *inode, struct file *file) ...@@ -123,7 +123,7 @@ static int uinput_open(struct inode *inode, struct file *file)
memset(newinput, 0, sizeof(struct input_dev)); memset(newinput, 0, sizeof(struct input_dev));
newdev->dev = newinput; newdev->dev = newinput;
file->private_data = newdev; file->private_data = newdev;
return 0; return 0;
...@@ -137,16 +137,16 @@ static int uinput_validate_absbits(struct input_dev *dev) ...@@ -137,16 +137,16 @@ static int uinput_validate_absbits(struct input_dev *dev)
{ {
unsigned int cnt; unsigned int cnt;
int retval = 0; int retval = 0;
for (cnt = 0; cnt < ABS_MAX; cnt++) { for (cnt = 0; cnt < ABS_MAX; cnt++) {
if (!test_bit(cnt, dev->absbit)) if (!test_bit(cnt, dev->absbit))
continue; continue;
if (/*!dev->absmin[cnt] || !dev->absmax[cnt] || */ if (/*!dev->absmin[cnt] || !dev->absmax[cnt] || */
(dev->absmax[cnt] <= dev->absmin[cnt])) { (dev->absmax[cnt] <= dev->absmin[cnt])) {
printk(KERN_DEBUG printk(KERN_DEBUG
"%s: invalid abs[%02x] min:%d max:%d\n", "%s: invalid abs[%02x] min:%d max:%d\n",
UINPUT_NAME, cnt, UINPUT_NAME, cnt,
dev->absmin[cnt], dev->absmax[cnt]); dev->absmin[cnt], dev->absmax[cnt]);
retval = -EINVAL; retval = -EINVAL;
break; break;
...@@ -154,7 +154,7 @@ static int uinput_validate_absbits(struct input_dev *dev) ...@@ -154,7 +154,7 @@ static int uinput_validate_absbits(struct input_dev *dev)
if ((dev->absflat[cnt] < dev->absmin[cnt]) || if ((dev->absflat[cnt] < dev->absmin[cnt]) ||
(dev->absflat[cnt] > dev->absmax[cnt])) { (dev->absflat[cnt] > dev->absmax[cnt])) {
printk(KERN_DEBUG printk(KERN_DEBUG
"%s: absflat[%02x] out of range: %d " "%s: absflat[%02x] out of range: %d "
"(min:%d/max:%d)\n", "(min:%d/max:%d)\n",
UINPUT_NAME, cnt, dev->absflat[cnt], UINPUT_NAME, cnt, dev->absflat[cnt],
...@@ -190,7 +190,7 @@ static int uinput_alloc_device(struct file *file, const char *buffer, size_t cou ...@@ -190,7 +190,7 @@ static int uinput_alloc_device(struct file *file, const char *buffer, size_t cou
goto exit; goto exit;
} }
if (NULL != dev->name) if (NULL != dev->name)
kfree(dev->name); kfree(dev->name);
size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1; size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
...@@ -229,7 +229,7 @@ static int uinput_alloc_device(struct file *file, const char *buffer, size_t cou ...@@ -229,7 +229,7 @@ static int uinput_alloc_device(struct file *file, const char *buffer, size_t cou
static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos) static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
{ {
struct uinput_device *udev = file->private_data; struct uinput_device *udev = file->private_data;
if (test_bit(UIST_CREATED, &(udev->state))) { if (test_bit(UIST_CREATED, &(udev->state))) {
struct input_event ev; struct input_event ev;
...@@ -247,7 +247,7 @@ static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t ...@@ -247,7 +247,7 @@ static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t
{ {
struct uinput_device *udev = file->private_data; struct uinput_device *udev = file->private_data;
int retval = 0; int retval = 0;
if (!test_bit(UIST_CREATED, &(udev->state))) if (!test_bit(UIST_CREATED, &(udev->state)))
return -ENODEV; return -ENODEV;
...@@ -255,16 +255,16 @@ static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t ...@@ -255,16 +255,16 @@ static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t
return -EAGAIN; return -EAGAIN;
retval = wait_event_interruptible(udev->waitq, retval = wait_event_interruptible(udev->waitq,
(udev->head != udev->tail) || (udev->head != udev->tail) ||
!test_bit(UIST_CREATED, &(udev->state))); !test_bit(UIST_CREATED, &(udev->state)));
if (retval) if (retval)
return retval; return retval;
if (!test_bit(UIST_CREATED, &(udev->state))) if (!test_bit(UIST_CREATED, &(udev->state)))
return -ENODEV; return -ENODEV;
while ((udev->head != udev->tail) && while ((udev->head != udev->tail) &&
(retval + sizeof(struct input_event) <= count)) { (retval + sizeof(struct input_event) <= count)) {
if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]), if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
sizeof(struct input_event))) return -EFAULT; sizeof(struct input_event))) return -EFAULT;
...@@ -284,7 +284,7 @@ static unsigned int uinput_poll(struct file *file, poll_table *wait) ...@@ -284,7 +284,7 @@ static unsigned int uinput_poll(struct file *file, poll_table *wait)
if (udev->head != udev->tail) if (udev->head != udev->tail)
return POLLIN | POLLRDNORM; return POLLIN | POLLRDNORM;
return 0; return 0;
} }
static int uinput_burn_device(struct uinput_device *udev) static int uinput_burn_device(struct uinput_device *udev)
...@@ -318,7 +318,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -318,7 +318,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
case UI_DEV_CREATE: case UI_DEV_CREATE:
retval = uinput_create_device(udev); retval = uinput_create_device(udev);
break; break;
case UI_DEV_DESTROY: case UI_DEV_DESTROY:
retval = uinput_destroy_device(udev); retval = uinput_destroy_device(udev);
break; break;
...@@ -330,7 +330,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -330,7 +330,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
} }
set_bit(arg, udev->dev->evbit); set_bit(arg, udev->dev->evbit);
break; break;
case UI_SET_KEYBIT: case UI_SET_KEYBIT:
if (arg > KEY_MAX) { if (arg > KEY_MAX) {
retval = -EINVAL; retval = -EINVAL;
...@@ -338,7 +338,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -338,7 +338,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
} }
set_bit(arg, udev->dev->keybit); set_bit(arg, udev->dev->keybit);
break; break;
case UI_SET_RELBIT: case UI_SET_RELBIT:
if (arg > REL_MAX) { if (arg > REL_MAX) {
retval = -EINVAL; retval = -EINVAL;
...@@ -346,7 +346,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -346,7 +346,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
} }
set_bit(arg, udev->dev->relbit); set_bit(arg, udev->dev->relbit);
break; break;
case UI_SET_ABSBIT: case UI_SET_ABSBIT:
if (arg > ABS_MAX) { if (arg > ABS_MAX) {
retval = -EINVAL; retval = -EINVAL;
...@@ -354,7 +354,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -354,7 +354,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
} }
set_bit(arg, udev->dev->absbit); set_bit(arg, udev->dev->absbit);
break; break;
case UI_SET_MSCBIT: case UI_SET_MSCBIT:
if (arg > MSC_MAX) { if (arg > MSC_MAX) {
retval = -EINVAL; retval = -EINVAL;
...@@ -362,7 +362,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -362,7 +362,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
} }
set_bit(arg, udev->dev->mscbit); set_bit(arg, udev->dev->mscbit);
break; break;
case UI_SET_LEDBIT: case UI_SET_LEDBIT:
if (arg > LED_MAX) { if (arg > LED_MAX) {
retval = -EINVAL; retval = -EINVAL;
...@@ -370,7 +370,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -370,7 +370,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
} }
set_bit(arg, udev->dev->ledbit); set_bit(arg, udev->dev->ledbit);
break; break;
case UI_SET_SNDBIT: case UI_SET_SNDBIT:
if (arg > SND_MAX) { if (arg > SND_MAX) {
retval = -EINVAL; retval = -EINVAL;
...@@ -378,7 +378,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -378,7 +378,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
} }
set_bit(arg, udev->dev->sndbit); set_bit(arg, udev->dev->sndbit);
break; break;
case UI_SET_FFBIT: case UI_SET_FFBIT:
if (arg > FF_MAX) { if (arg > FF_MAX) {
retval = -EINVAL; retval = -EINVAL;
...@@ -386,7 +386,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd ...@@ -386,7 +386,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
} }
set_bit(arg, udev->dev->ffbit); set_bit(arg, udev->dev->ffbit);
break; break;
default: default:
retval = -EFAULT; retval = -EFAULT;
} }
......
...@@ -14,6 +14,25 @@ ...@@ -14,6 +14,25 @@
#include "psmouse.h" #include "psmouse.h"
#include "logips2pp.h" #include "logips2pp.h"
/* Logitech mouse types */
#define PS2PP_KIND_WHEEL 1
#define PS2PP_KIND_MX 2
#define PS2PP_KIND_TP3 3
/* Logitech mouse features */
#define PS2PP_WHEEL 0x01
#define PS2PP_HWHEEL 0x02
#define PS2PP_SIDE_BTN 0x04
#define PS2PP_EXTRA_BTN 0x08
#define PS2PP_TASK_BTN 0x10
#define PS2PP_NAV_BTN 0x20
struct ps2pp_info {
const int model;
unsigned const int kind;
unsigned const int features;
};
/* /*
* Process a PS2++ or PS2T++ packet. * Process a PS2++ or PS2T++ packet.
*/ */
...@@ -63,7 +82,6 @@ void ps2pp_process_packet(struct psmouse *psmouse) ...@@ -63,7 +82,6 @@ void ps2pp_process_packet(struct psmouse *psmouse)
packet[0] &= 0x0f; packet[0] &= 0x0f;
packet[1] = 0; packet[1] = 0;
packet[2] = 0; packet[2] = 0;
} }
} }
...@@ -76,18 +94,9 @@ void ps2pp_process_packet(struct psmouse *psmouse) ...@@ -76,18 +94,9 @@ void ps2pp_process_packet(struct psmouse *psmouse)
static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command) static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned char command)
{ {
unsigned char d; if (psmouse_sliced_command(psmouse, command))
int i;
if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
return -1; return -1;
for (i = 6; i >= 0; i -= 2) {
d = (command >> i) & 3;
if(psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
return -1;
}
if (psmouse_command(psmouse, param, PSMOUSE_CMD_POLL)) if (psmouse_command(psmouse, param, PSMOUSE_CMD_POLL))
return -1; return -1;
...@@ -99,7 +108,7 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha ...@@ -99,7 +108,7 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha
* enabled if we do nothing to it. Of course I put this in because I want it * enabled if we do nothing to it. Of course I put this in because I want it
* disabled :P * disabled :P
* 1 - enabled (if previously disabled, also default) * 1 - enabled (if previously disabled, also default)
* 0/2 - disabled * 0/2 - disabled
*/ */
static void ps2pp_set_smartscroll(struct psmouse *psmouse) static void ps2pp_set_smartscroll(struct psmouse *psmouse)
...@@ -113,14 +122,11 @@ static void ps2pp_set_smartscroll(struct psmouse *psmouse) ...@@ -113,14 +122,11 @@ static void ps2pp_set_smartscroll(struct psmouse *psmouse)
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
if (psmouse_smartscroll == 1) if (psmouse_smartscroll < 2) {
param[0] = 1; /* 0 - disabled, 1 - enabled */
else param[0] = psmouse_smartscroll;
if (psmouse_smartscroll > 2) psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
return; }
/* else leave param[0] == 0 to disable */
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
} }
/* /*
...@@ -138,133 +144,167 @@ void ps2pp_set_800dpi(struct psmouse *psmouse) ...@@ -138,133 +144,167 @@ void ps2pp_set_800dpi(struct psmouse *psmouse)
psmouse_command(psmouse, &param, PSMOUSE_CMD_SETRES); psmouse_command(psmouse, &param, PSMOUSE_CMD_SETRES);
} }
static struct ps2pp_info *get_model_info(unsigned char model)
{
static struct ps2pp_info ps2pp_list[] = {
{ 12, 0, PS2PP_SIDE_BTN},
{ 13, 0, 0 },
{ 40, 0, PS2PP_SIDE_BTN },
{ 41, 0, PS2PP_SIDE_BTN },
{ 42, 0, PS2PP_SIDE_BTN },
{ 43, 0, PS2PP_SIDE_BTN },
{ 50, 0, 0 },
{ 51, 0, 0 },
{ 52, PS2PP_KIND_WHEEL, PS2PP_SIDE_BTN | PS2PP_WHEEL },
{ 53, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 61, PS2PP_KIND_MX,
PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, /* MX700 */
{ 73, 0, PS2PP_SIDE_BTN },
{ 75, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 76, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 80, PS2PP_KIND_WHEEL, PS2PP_SIDE_BTN | PS2PP_WHEEL },
{ 81, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 83, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 88, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 96, 0, 0 },
{ 97, PS2PP_KIND_TP3, PS2PP_WHEEL | PS2PP_HWHEEL },
{ 100, PS2PP_KIND_MX,
PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, /* MX510 */
{ 112, PS2PP_KIND_MX,
PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, /* MX500 */
{ 114, PS2PP_KIND_MX,
PS2PP_WHEEL | PS2PP_SIDE_BTN |
PS2PP_TASK_BTN | PS2PP_EXTRA_BTN }, /* M310 */
{ }
};
int i;
for (i = 0; ps2pp_list[i].model; i++)
if (model == ps2pp_list[i].model)
return &ps2pp_list[i];
return NULL;
}
/* /*
* Detect the exact model and features of a PS2++ or PS2T++ Logitech mouse or * Set up input device's properties based on the detected mouse model.
* touchpad.
*/ */
static int ps2pp_detect_model(struct psmouse *psmouse, unsigned char *param) static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_info *model_info)
{ {
int i; if (model_info->features & PS2PP_SIDE_BTN)
static struct _logips2_list { set_bit(BTN_SIDE, psmouse->dev.keybit);
const int model;
unsigned const int features; if (model_info->features & PS2PP_EXTRA_BTN)
} logips2pp_list [] = { set_bit(BTN_EXTRA, psmouse->dev.keybit);
{ 12, PS2PP_4BTN},
{ 13, 0 },
{ 40, PS2PP_4BTN },
{ 41, PS2PP_4BTN },
{ 42, PS2PP_4BTN },
{ 43, PS2PP_4BTN },
{ 50, 0 },
{ 51, 0 },
{ 52, PS2PP_4BTN | PS2PP_WHEEL },
{ 53, PS2PP_WHEEL },
{ 61, PS2PP_WHEEL | PS2PP_MX }, /* MX700 */
{ 73, PS2PP_4BTN },
{ 75, PS2PP_WHEEL },
{ 76, PS2PP_WHEEL },
{ 80, PS2PP_4BTN | PS2PP_WHEEL },
{ 81, PS2PP_WHEEL },
{ 83, PS2PP_WHEEL },
{ 88, PS2PP_WHEEL },
{ 96, 0 },
{ 97, 0 },
{ 100 , PS2PP_WHEEL | PS2PP_MX }, /* MX510 */
{ 112 , PS2PP_WHEEL | PS2PP_MX }, /* MX500 */
{ 114 , PS2PP_WHEEL | PS2PP_MX | PS2PP_MX310 }, /* MX310 */
{ }
};
psmouse->vendor = "Logitech"; if (model_info->features & PS2PP_TASK_BTN)
psmouse->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); set_bit(BTN_TASK, psmouse->dev.keybit);
if (param[1] < 3) if (model_info->features & PS2PP_NAV_BTN) {
clear_bit(BTN_MIDDLE, psmouse->dev.keybit); set_bit(BTN_FORWARD, psmouse->dev.keybit);
if (param[1] < 2) set_bit(BTN_BACK, psmouse->dev.keybit);
clear_bit(BTN_RIGHT, psmouse->dev.keybit); }
psmouse->type = PSMOUSE_PS2; if (model_info->features & PS2PP_WHEEL)
set_bit(REL_WHEEL, psmouse->dev.relbit);
for (i = 0; logips2pp_list[i].model; i++){ if (model_info->features & PS2PP_HWHEEL)
if (logips2pp_list[i].model == psmouse->model){ set_bit(REL_HWHEEL, psmouse->dev.relbit);
psmouse->type = PSMOUSE_PS2PP;
if (logips2pp_list[i].features & PS2PP_4BTN)
set_bit(BTN_SIDE, psmouse->dev.keybit);
if (logips2pp_list[i].features & PS2PP_WHEEL){ switch (model_info->kind) {
set_bit(REL_WHEEL, psmouse->dev.relbit); case PS2PP_KIND_WHEEL:
psmouse->name = "Wheel Mouse"; psmouse->name = "Wheel Mouse";
} break;
if (logips2pp_list[i].features & PS2PP_MX) {
set_bit(BTN_SIDE, psmouse->dev.keybit); case PS2PP_KIND_MX:
set_bit(BTN_EXTRA, psmouse->dev.keybit); psmouse->name = "MX Mouse";
set_bit(BTN_TASK, psmouse->dev.keybit); break;
if (!(logips2pp_list[i].features & PS2PP_MX310)){
set_bit(BTN_BACK, psmouse->dev.keybit); case PS2PP_KIND_TP3:
set_bit(BTN_FORWARD, psmouse->dev.keybit); psmouse->name = "TouchPad 3";
}
psmouse->name = "MX Mouse";
}
break; break;
}
} }
}
/* /*
* Do Logitech PS2++ / PS2T++ magic init. * Logitech magic init. Detect whether the mouse is a Logitech one
* and its exact model and try turning on extended protocol for ones
* that support it.
*/ */
if (psmouse->type == PSMOUSE_PS2PP) {
if (psmouse->model == 97) { /* TouchPad 3 */ int ps2pp_init(struct psmouse *psmouse, int set_properties)
{
unsigned char param[4];
unsigned char protocol = PSMOUSE_PS2;
unsigned char model, buttons;
struct ps2pp_info *model_info;
param[0] = 0;
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
param[1] = 0;
psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
if (param[1] != 0) {
model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
buttons = param[1];
model_info = get_model_info(model);
set_bit(REL_WHEEL, psmouse->dev.relbit); /*
set_bit(REL_HWHEEL, psmouse->dev.relbit); * Do Logitech PS2++ / PS2T++ magic init.
*/
if (model == 97) { /* Touch Pad 3 */
param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; /* Unprotect RAM */ /* Unprotect RAM */
param[0] = 0x11; param[1] = 0x04; param[2] = 0x68;
psmouse_command(psmouse, param, 0x30d1); psmouse_command(psmouse, param, 0x30d1);
param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; /* Enable features */ /* Enable features */
param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b;
psmouse_command(psmouse, param, 0x30d1); psmouse_command(psmouse, param, 0x30d1);
param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; /* Enable PS2++ */ /* Enable PS2++ */
param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3;
psmouse_command(psmouse, param, 0x30d1); psmouse_command(psmouse, param, 0x30d1);
param[0] = 0; param[0] = 0;
if (!psmouse_command(psmouse, param, 0x13d1) && if (!psmouse_command(psmouse, param, 0x13d1) &&
param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) { param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
psmouse->name = "TouchPad 3"; protocol = PSMOUSE_PS2TPP;
return PSMOUSE_PS2TPP;
} }
} else { } else if (get_model_info(model) != NULL) {
param[0] = param[1] = param[2] = 0; param[0] = param[1] = param[2] = 0;
ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */ ps2pp_cmd(psmouse, param, 0x39); /* Magic knock */
ps2pp_cmd(psmouse, param, 0xDB); ps2pp_cmd(psmouse, param, 0xDB);
if ((param[0] & 0x78) == 0x48 && (param[1] & 0xf3) == 0xc2 && if ((param[0] & 0x78) == 0x48 &&
(param[2] & 3) == ((param[1] >> 2) & 3)) { (param[1] & 0xf3) == 0xc2 &&
ps2pp_set_smartscroll(psmouse); (param[2] & 0x03) == ((param[1] >> 2) & 3)) {
return PSMOUSE_PS2PP; ps2pp_set_smartscroll(psmouse);
protocol = PSMOUSE_PS2PP;
} }
} }
}
return 0; if (set_properties) {
} psmouse->vendor = "Logitech";
psmouse->model = model;
/* if (buttons < 3)
* Logitech magic init. clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
*/ if (buttons < 2)
int ps2pp_detect(struct psmouse *psmouse) clear_bit(BTN_RIGHT, psmouse->dev.keybit);
{
unsigned char param[4];
param[0] = 0; if (model_info)
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES); ps2pp_set_model_properties(psmouse, model_info);
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); }
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11); }
psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11);
param[1] = 0;
psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
return param[1] != 0 ? ps2pp_detect_model(psmouse, param) : 0; return protocol;
} }
...@@ -11,13 +11,8 @@ ...@@ -11,13 +11,8 @@
#ifndef _LOGIPS2PP_H #ifndef _LOGIPS2PP_H
#define _LOGIPS2PP_H #define _LOGIPS2PP_H
#define PS2PP_4BTN 0x01
#define PS2PP_WHEEL 0x02
#define PS2PP_MX 0x04
#define PS2PP_MX310 0x08
struct psmouse;
void ps2pp_process_packet(struct psmouse *psmouse); void ps2pp_process_packet(struct psmouse *psmouse);
void ps2pp_set_800dpi(struct psmouse *psmouse); void ps2pp_set_800dpi(struct psmouse *psmouse);
int ps2pp_detect(struct psmouse *psmouse); int ps2pp_init(struct psmouse *psmouse, int set_properties);
#endif #endif
...@@ -43,9 +43,9 @@ int psmouse_smartscroll = 1; ...@@ -43,9 +43,9 @@ int psmouse_smartscroll = 1;
module_param_named(smartscroll, psmouse_smartscroll, bool, 0); module_param_named(smartscroll, psmouse_smartscroll, bool, 0);
MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled."); MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
unsigned int psmouse_resetafter; static unsigned int psmouse_resetafter;
module_param_named(resetafter, psmouse_resetafter, uint, 0); module_param_named(resetafter, psmouse_resetafter, uint, 0);
MODULE_PARM_DESC(resetafter, "Reset Synaptics Touchpad after so many bad packets (0 = never)."); MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
__obsolete_setup("psmouse_noext"); __obsolete_setup("psmouse_noext");
__obsolete_setup("psmouse_resolution="); __obsolete_setup("psmouse_resolution=");
...@@ -56,15 +56,22 @@ __obsolete_setup("psmouse_rate="); ...@@ -56,15 +56,22 @@ __obsolete_setup("psmouse_rate=");
static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"}; static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "PS2T++", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2"};
/* /*
* psmouse_process_packet() analyzes the PS/2 mouse packet contents and * psmouse_process_byte() analyzes the PS/2 data stream and reports
* reports relevant events to the input module. * relevant events to the input module once full packet has arrived.
*/ */
static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs) static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
{ {
struct input_dev *dev = &psmouse->dev; struct input_dev *dev = &psmouse->dev;
unsigned char *packet = psmouse->packet; unsigned char *packet = psmouse->packet;
if (psmouse->pktcnt < 3 + (psmouse->type >= PSMOUSE_GENPS))
return PSMOUSE_GOOD_DATA;
/*
* Full packet accumulated, process it
*/
input_regs(dev, regs); input_regs(dev, regs);
/* /*
...@@ -112,6 +119,8 @@ static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs ...@@ -112,6 +119,8 @@ static void psmouse_process_packet(struct psmouse *psmouse, struct pt_regs *regs
input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0); input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
input_sync(dev); input_sync(dev);
return PSMOUSE_FULL_PACKET;
} }
/* /*
...@@ -123,6 +132,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, ...@@ -123,6 +132,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
unsigned char data, unsigned int flags, struct pt_regs *regs) unsigned char data, unsigned int flags, struct pt_regs *regs)
{ {
struct psmouse *psmouse = serio->private; struct psmouse *psmouse = serio->private;
psmouse_ret_t rc;
if (psmouse->state == PSMOUSE_IGNORE) if (psmouse->state == PSMOUSE_IGNORE)
goto out; goto out;
...@@ -180,7 +190,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, ...@@ -180,7 +190,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
if (psmouse->pktcnt == 2) { if (psmouse->pktcnt == 2) {
if (psmouse->packet[1] == PSMOUSE_RET_ID) { if (psmouse->packet[1] == PSMOUSE_RET_ID) {
psmouse->state = PSMOUSE_IGNORE; psmouse->state = PSMOUSE_IGNORE;
serio_rescan(serio); serio_reconnect(serio);
goto out; goto out;
} }
if (psmouse->type == PSMOUSE_SYNAPTICS) { if (psmouse->type == PSMOUSE_SYNAPTICS) {
...@@ -193,19 +203,32 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, ...@@ -193,19 +203,32 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
} }
} }
if (psmouse->type == PSMOUSE_SYNAPTICS) { rc = psmouse->protocol_handler(psmouse, regs);
/*
* The synaptics driver has its own resync logic,
* so it needs to receive all bytes one at a time.
*/
synaptics_process_byte(psmouse, regs);
goto out;
}
if (psmouse->pktcnt == 3 + (psmouse->type >= PSMOUSE_GENPS)) { switch (rc) {
psmouse_process_packet(psmouse, regs); case PSMOUSE_BAD_DATA:
psmouse->pktcnt = 0; printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",
goto out; psmouse->name, psmouse->phys, psmouse->pktcnt);
psmouse->pktcnt = 0;
if (++psmouse->out_of_sync == psmouse_resetafter) {
psmouse->state = PSMOUSE_IGNORE;
printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
serio_reconnect(psmouse->serio);
}
break;
case PSMOUSE_FULL_PACKET:
psmouse->pktcnt = 0;
if (psmouse->out_of_sync) {
psmouse->out_of_sync = 0;
printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",
psmouse->name, psmouse->phys);
}
break;
case PSMOUSE_GOOD_DATA:
break;
} }
out: out:
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -288,6 +311,30 @@ int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command) ...@@ -288,6 +311,30 @@ int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command)
} }
/*
* psmouse_sliced_command() sends an extended PS/2 command to the mouse
* using sliced syntax, understood by advanced devices, such as Logitech
* or Synaptics touchpads. The command is encoded as:
* 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
* is the command.
*/
int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command)
{
int i;
if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
return -1;
for (i = 6; i >= 0; i -= 2) {
unsigned char d = (command >> i) & 3;
if (psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
return -1;
}
return 0;
}
/* /*
* psmouse_reset() resets the mouse into power-on state. * psmouse_reset() resets the mouse into power-on state.
*/ */
...@@ -363,31 +410,31 @@ static int im_explorer_detect(struct psmouse *psmouse) ...@@ -363,31 +410,31 @@ static int im_explorer_detect(struct psmouse *psmouse)
* the mouse may have. * the mouse may have.
*/ */
static int psmouse_extensions(struct psmouse *psmouse) static int psmouse_extensions(struct psmouse *psmouse,
unsigned int max_proto, int set_properties)
{ {
int synaptics_hardware = 0; int synaptics_hardware = 0;
psmouse->vendor = "Generic";
psmouse->name = "Mouse";
psmouse->model = 0;
/* /*
* Try Synaptics TouchPad * Try Synaptics TouchPad
*/ */
if (psmouse_max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) { if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse)) {
synaptics_hardware = 1; synaptics_hardware = 1;
psmouse->vendor = "Synaptics";
psmouse->name = "TouchPad";
if (psmouse_max_proto > PSMOUSE_IMEX) { if (set_properties) {
if (synaptics_init(psmouse) == 0) psmouse->vendor = "Synaptics";
psmouse->name = "TouchPad";
}
if (max_proto > PSMOUSE_IMEX) {
if (!set_properties || synaptics_init(psmouse) == 0)
return PSMOUSE_SYNAPTICS; return PSMOUSE_SYNAPTICS;
/* /*
* Some Synaptics touchpads can emulate extended protocols (like IMPS/2). * Some Synaptics touchpads can emulate extended protocols (like IMPS/2).
* Unfortunately Logitech/Genius probes confuse some firmware versions so * Unfortunately Logitech/Genius probes confuse some firmware versions so
* we'll have to skip them. * we'll have to skip them.
*/ */
psmouse_max_proto = PSMOUSE_IMEX; max_proto = PSMOUSE_IMEX;
} }
/* /*
* Make sure that touchpad is in relative mode, gestures (taps) are enabled * Make sure that touchpad is in relative mode, gestures (taps) are enabled
...@@ -395,35 +442,46 @@ static int psmouse_extensions(struct psmouse *psmouse) ...@@ -395,35 +442,46 @@ static int psmouse_extensions(struct psmouse *psmouse)
synaptics_reset(psmouse); synaptics_reset(psmouse);
} }
if (psmouse_max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) { if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse)) {
set_bit(BTN_EXTRA, psmouse->dev.keybit);
set_bit(BTN_SIDE, psmouse->dev.keybit); if (set_properties) {
set_bit(REL_WHEEL, psmouse->dev.relbit); set_bit(BTN_EXTRA, psmouse->dev.keybit);
set_bit(BTN_SIDE, psmouse->dev.keybit);
set_bit(REL_WHEEL, psmouse->dev.relbit);
psmouse->vendor = "Genius";
psmouse->name = "Wheel Mouse";
}
psmouse->vendor = "Genius";
psmouse->name = "Wheel Mouse";
return PSMOUSE_GENPS; return PSMOUSE_GENPS;
} }
if (psmouse_max_proto > PSMOUSE_IMEX) { if (max_proto > PSMOUSE_IMEX) {
int type = ps2pp_detect(psmouse); int type = ps2pp_init(psmouse, set_properties);
if (type) if (type > PSMOUSE_PS2)
return type; return type;
} }
if (psmouse_max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) { if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse)) {
set_bit(REL_WHEEL, psmouse->dev.relbit);
if (psmouse_max_proto >= PSMOUSE_IMEX && if (set_properties) {
im_explorer_detect(psmouse)) { set_bit(REL_WHEEL, psmouse->dev.relbit);
set_bit(BTN_SIDE, psmouse->dev.keybit); set_bit(BTN_SIDE, psmouse->dev.keybit);
set_bit(BTN_EXTRA, psmouse->dev.keybit); set_bit(BTN_EXTRA, psmouse->dev.keybit);
if (!psmouse->name)
psmouse->name = "Explorer Mouse";
}
return PSMOUSE_IMEX;
}
if (max_proto >= PSMOUSE_IMPS && intellimouse_detect(psmouse)) {
psmouse->name = "Explorer Mouse"; if (set_properties) {
return PSMOUSE_IMEX; set_bit(REL_WHEEL, psmouse->dev.relbit);
if (!psmouse->name)
psmouse->name = "Wheel Mouse";
} }
psmouse->name = "Wheel Mouse";
return PSMOUSE_IMPS; return PSMOUSE_IMPS;
} }
...@@ -473,12 +531,7 @@ static int psmouse_probe(struct psmouse *psmouse) ...@@ -473,12 +531,7 @@ static int psmouse_probe(struct psmouse *psmouse)
if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS)) if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_RESET_DIS))
printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", psmouse->serio->phys); printk(KERN_WARNING "psmouse.c: Failed to reset mouse on %s\n", psmouse->serio->phys);
/* return 0;
* And here we try to determine if it has any extensions over the
* basic PS/2 3-button mouse.
*/
return psmouse->type = psmouse_extensions(psmouse);
} }
/* /*
...@@ -616,7 +669,6 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev) ...@@ -616,7 +669,6 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
psmouse->state = PSMOUSE_CMD_MODE; psmouse->state = PSMOUSE_CMD_MODE;
psmouse->serio = serio; psmouse->serio = serio;
psmouse->dev.private = psmouse; psmouse->dev.private = psmouse;
...@@ -628,13 +680,21 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev) ...@@ -628,13 +680,21 @@ static void psmouse_connect(struct serio *serio, struct serio_dev *dev)
return; return;
} }
if (psmouse_probe(psmouse) <= 0) { if (psmouse_probe(psmouse) < 0) {
serio_close(serio); serio_close(serio);
kfree(psmouse); kfree(psmouse);
serio->private = NULL; serio->private = NULL;
return; return;
} }
psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);
if (!psmouse->vendor)
psmouse->vendor = "Generic";
if (!psmouse->name)
psmouse->name = "Mouse";
if (!psmouse->protocol_handler)
psmouse->protocol_handler = psmouse_process_byte;
sprintf(psmouse->devname, "%s %s %s", sprintf(psmouse->devname, "%s %s %s",
psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name); psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name);
sprintf(psmouse->phys, "%s/input0", sprintf(psmouse->phys, "%s/input0",
...@@ -668,27 +728,24 @@ static int psmouse_reconnect(struct serio *serio) ...@@ -668,27 +728,24 @@ static int psmouse_reconnect(struct serio *serio)
{ {
struct psmouse *psmouse = serio->private; struct psmouse *psmouse = serio->private;
struct serio_dev *dev = serio->dev; struct serio_dev *dev = serio->dev;
int old_type;
if (!dev || !psmouse) { if (!dev || !psmouse) {
printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n"); printk(KERN_DEBUG "psmouse: reconnect request, but serio is disconnected, ignoring...\n");
return -1; return -1;
} }
old_type = psmouse->type;
psmouse->state = PSMOUSE_CMD_MODE; psmouse->state = PSMOUSE_CMD_MODE;
psmouse->type = psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = 0; psmouse->acking = psmouse->cmdcnt = psmouse->pktcnt = psmouse->out_of_sync = 0;
if (psmouse->reconnect) { if (psmouse->reconnect) {
if (psmouse->reconnect(psmouse)) if (psmouse->reconnect(psmouse))
return -1; return -1;
} else if (psmouse_probe(psmouse) != old_type) } else if (psmouse_probe(psmouse) < 0 ||
psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0))
return -1; return -1;
/* ok, the device type (and capabilities) match the old one, /* ok, the device type (and capabilities) match the old one,
* we can continue using it, complete intialization * we can continue using it, complete intialization
*/ */
psmouse->type = old_type;
psmouse_initialize(psmouse); psmouse_initialize(psmouse);
if (psmouse->ptport) { if (psmouse->ptport) {
......
...@@ -22,6 +22,13 @@ ...@@ -22,6 +22,13 @@
#define PSMOUSE_ACTIVATED 1 #define PSMOUSE_ACTIVATED 1
#define PSMOUSE_IGNORE 2 #define PSMOUSE_IGNORE 2
/* psmouse protocol handler return codes */
typedef enum {
PSMOUSE_BAD_DATA,
PSMOUSE_GOOD_DATA,
PSMOUSE_FULL_PACKET
} psmouse_ret_t;
struct psmouse; struct psmouse;
struct psmouse_ptport { struct psmouse_ptport {
...@@ -45,6 +52,7 @@ struct psmouse { ...@@ -45,6 +52,7 @@ struct psmouse {
unsigned char type; unsigned char type;
unsigned char model; unsigned char model;
unsigned long last; unsigned long last;
unsigned long out_of_sync;
unsigned char state; unsigned char state;
char acking; char acking;
volatile char ack; volatile char ack;
...@@ -52,6 +60,7 @@ struct psmouse { ...@@ -52,6 +60,7 @@ struct psmouse {
char devname[64]; char devname[64];
char phys[32]; char phys[32];
psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse, struct pt_regs *regs);
int (*reconnect)(struct psmouse *psmouse); int (*reconnect)(struct psmouse *psmouse);
void (*disconnect)(struct psmouse *psmouse); void (*disconnect)(struct psmouse *psmouse);
}; };
...@@ -65,10 +74,10 @@ struct psmouse { ...@@ -65,10 +74,10 @@ struct psmouse {
#define PSMOUSE_SYNAPTICS 7 #define PSMOUSE_SYNAPTICS 7
int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command); int psmouse_command(struct psmouse *psmouse, unsigned char *param, int command);
int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
int psmouse_reset(struct psmouse *psmouse); int psmouse_reset(struct psmouse *psmouse);
extern int psmouse_smartscroll; extern int psmouse_smartscroll;
extern unsigned int psmouse_rate; extern unsigned int psmouse_rate;
extern unsigned int psmouse_resetafter;
#endif /* _PSMOUSE_H */ #endif /* _PSMOUSE_H */
...@@ -43,34 +43,12 @@ ...@@ -43,34 +43,12 @@
* Synaptics communications functions * Synaptics communications functions
****************************************************************************/ ****************************************************************************/
/*
* Use the Synaptics extended ps/2 syntax to write a special command byte.
* special command: 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
* is the command. A 0xF3 or 0xE9 must follow (see synaptics_send_cmd
* and synaptics_mode_cmd)
*/
static int synaptics_special_cmd(struct psmouse *psmouse, unsigned char command)
{
int i;
if (psmouse_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11))
return -1;
for (i = 6; i >= 0; i -= 2) {
unsigned char d = (command >> i) & 3;
if (psmouse_command(psmouse, &d, PSMOUSE_CMD_SETRES))
return -1;
}
return 0;
}
/* /*
* Send a command to the synpatics touchpad by special commands * Send a command to the synpatics touchpad by special commands
*/ */
static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param)
{ {
if (synaptics_special_cmd(psmouse, c)) if (psmouse_sliced_command(psmouse, c))
return -1; return -1;
if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO)) if (psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO))
return -1; return -1;
...@@ -84,7 +62,7 @@ static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode) ...@@ -84,7 +62,7 @@ static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode)
{ {
unsigned char param[1]; unsigned char param[1];
if (synaptics_special_cmd(psmouse, mode)) if (psmouse_sliced_command(psmouse, mode))
return -1; return -1;
param[0] = SYN_PS_SET_MODE2; param[0] = SYN_PS_SET_MODE2;
if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE)) if (psmouse_command(psmouse, param, PSMOUSE_CMD_SETRATE))
...@@ -118,17 +96,31 @@ static int synaptics_capability(struct psmouse *psmouse) ...@@ -118,17 +96,31 @@ static int synaptics_capability(struct psmouse *psmouse)
if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap)) if (synaptics_send_cmd(psmouse, SYN_QUE_CAPABILITIES, cap))
return -1; return -1;
priv->capabilities = (cap[0]<<16) | (cap[1]<<8) | cap[2]; priv->capabilities = (cap[0] << 16) | (cap[1] << 8) | cap[2];
priv->ext_cap = 0; priv->ext_cap = 0;
if (!SYN_CAP_VALID(priv->capabilities)) if (!SYN_CAP_VALID(priv->capabilities))
return -1; return -1;
if (SYN_EXT_CAP_REQUESTS(priv->capabilities)) { /*
* Unless capExtended is set the rest of the flags should be ignored
*/
if (!SYN_CAP_EXTENDED(priv->capabilities))
priv->capabilities = 0;
if (SYN_EXT_CAP_REQUESTS(priv->capabilities) >= 1) {
if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) { if (synaptics_send_cmd(psmouse, SYN_QUE_EXT_CAPAB, cap)) {
printk(KERN_ERR "Synaptics claims to have extended capabilities," printk(KERN_ERR "Synaptics claims to have extended capabilities,"
" but I'm not able to read them."); " but I'm not able to read them.");
} else } else {
priv->ext_cap = (cap[0]<<16) | (cap[1]<<8) | cap[2]; priv->ext_cap = (cap[0] << 16) | (cap[1] << 8) | cap[2];
/*
* if nExtBtn is greater than 8 it should be considered
* invalid and treated as 0
*/
if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) > 8)
priv->ext_cap &= 0xff0fff;
}
} }
return 0; return 0;
} }
...@@ -167,11 +159,12 @@ static void print_ident(struct synaptics_data *priv) ...@@ -167,11 +159,12 @@ static void print_ident(struct synaptics_data *priv)
if (SYN_CAP_EXTENDED(priv->capabilities)) { if (SYN_CAP_EXTENDED(priv->capabilities)) {
printk(KERN_INFO " Touchpad has extended capability bits\n"); printk(KERN_INFO " Touchpad has extended capability bits\n");
if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) <= 8)
printk(KERN_INFO " -> %d multi-buttons, i.e. besides standard buttons\n", printk(KERN_INFO " -> %d multi-buttons, i.e. besides standard buttons\n",
(int)(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))); (int)(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)));
else if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
printk(KERN_INFO " -> middle button\n");
if (SYN_CAP_FOUR_BUTTON(priv->capabilities))
printk(KERN_INFO " -> four buttons\n"); printk(KERN_INFO " -> four buttons\n");
if (SYN_CAP_MULTIFINGER(priv->capabilities)) if (SYN_CAP_MULTIFINGER(priv->capabilities))
printk(KERN_INFO " -> multifinger detection\n"); printk(KERN_INFO " -> multifinger detection\n");
...@@ -219,21 +212,12 @@ static int synaptics_set_mode(struct psmouse *psmouse, int mode) ...@@ -219,21 +212,12 @@ static int synaptics_set_mode(struct psmouse *psmouse, int mode)
/***************************************************************************** /*****************************************************************************
* Synaptics pass-through PS/2 port support * Synaptics pass-through PS/2 port support
****************************************************************************/ ****************************************************************************/
static int synaptics_pt_open(struct serio *port)
{
return 0;
}
static void synaptics_pt_close(struct serio *port)
{
}
static int synaptics_pt_write(struct serio *port, unsigned char c) static int synaptics_pt_write(struct serio *port, unsigned char c)
{ {
struct psmouse *parent = port->driver; struct psmouse *parent = port->driver;
char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */ char rate_param = SYN_PS_CLIENT_CMD; /* indicates that we want pass-through port */
if (synaptics_special_cmd(parent, c)) if (psmouse_sliced_command(parent, c))
return -1; return -1;
if (psmouse_command(parent, &rate_param, PSMOUSE_CMD_SETRATE)) if (psmouse_command(parent, &rate_param, PSMOUSE_CMD_SETRATE))
return -1; return -1;
...@@ -289,165 +273,11 @@ static void synaptics_pt_create(struct psmouse *psmouse) ...@@ -289,165 +273,11 @@ static void synaptics_pt_create(struct psmouse *psmouse)
port->serio.name = "Synaptics pass-through"; port->serio.name = "Synaptics pass-through";
port->serio.phys = "synaptics-pt/serio0"; port->serio.phys = "synaptics-pt/serio0";
port->serio.write = synaptics_pt_write; port->serio.write = synaptics_pt_write;
port->serio.open = synaptics_pt_open;
port->serio.close = synaptics_pt_close;
port->serio.driver = psmouse; port->serio.driver = psmouse;
port->activate = synaptics_pt_activate; port->activate = synaptics_pt_activate;
} }
/*****************************************************************************
* Driver initialization/cleanup functions
****************************************************************************/
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 set_input_params(struct input_dev *dev, struct synaptics_data *priv)
{
set_bit(EV_ABS, dev->evbit);
set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
set_bit(ABS_TOOL_WIDTH, dev->absbit);
set_bit(EV_KEY, dev->evbit);
set_bit(BTN_TOUCH, dev->keybit);
set_bit(BTN_TOOL_FINGER, dev->keybit);
set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
set_bit(BTN_LEFT, dev->keybit);
set_bit(BTN_RIGHT, dev->keybit);
set_bit(BTN_FORWARD, dev->keybit);
set_bit(BTN_BACK, dev->keybit);
if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) {
switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
default:
/*
* if nExtBtn is greater than 8 it should be considered
* invalid and treated as 0
*/
break;
case 8:
set_bit(BTN_7, dev->keybit);
set_bit(BTN_6, dev->keybit);
case 6:
set_bit(BTN_5, dev->keybit);
set_bit(BTN_4, dev->keybit);
case 4:
set_bit(BTN_3, dev->keybit);
set_bit(BTN_2, dev->keybit);
case 2:
set_bit(BTN_1, dev->keybit);
set_bit(BTN_0, dev->keybit);
break;
}
}
clear_bit(EV_REL, dev->evbit);
clear_bit(REL_X, dev->relbit);
clear_bit(REL_Y, dev->relbit);
}
void synaptics_reset(struct psmouse *psmouse)
{
/* reset touchpad back to relative mode, gestures enabled */
synaptics_mode_cmd(psmouse, 0);
}
static void synaptics_disconnect(struct psmouse *psmouse)
{
synaptics_reset(psmouse);
kfree(psmouse->private);
}
static int synaptics_reconnect(struct psmouse *psmouse)
{
struct synaptics_data *priv = psmouse->private;
struct synaptics_data old_priv = *priv;
if (!synaptics_detect(psmouse))
return -1;
if (synaptics_query_hardware(psmouse)) {
printk(KERN_ERR "Unable to query Synaptics hardware.\n");
return -1;
}
if (old_priv.identity != priv->identity ||
old_priv.model_id != priv->model_id ||
old_priv.capabilities != priv->capabilities ||
old_priv.ext_cap != priv->ext_cap)
return -1;
if (synaptics_set_mode(psmouse, 0)) {
printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
return -1;
}
return 0;
}
int synaptics_detect(struct psmouse *psmouse)
{
unsigned char param[4];
param[0] = 0;
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
return param[1] == 0x47;
}
int synaptics_init(struct psmouse *psmouse)
{
struct synaptics_data *priv;
psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL);
if (!priv)
return -1;
memset(priv, 0, sizeof(struct synaptics_data));
if (synaptics_query_hardware(psmouse)) {
printk(KERN_ERR "Unable to query Synaptics hardware.\n");
goto init_fail;
}
if (synaptics_set_mode(psmouse, 0)) {
printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
goto init_fail;
}
priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
if (SYN_CAP_EXTENDED(priv->capabilities) && SYN_CAP_PASS_THROUGH(priv->capabilities))
synaptics_pt_create(psmouse);
print_ident(priv);
set_input_params(&psmouse->dev, priv);
psmouse->disconnect = synaptics_disconnect;
psmouse->reconnect = synaptics_reconnect;
return 0;
init_fail:
kfree(priv);
return -1;
}
/***************************************************************************** /*****************************************************************************
* Functions to interpret the absolute mode packets * Functions to interpret the absolute mode packets
****************************************************************************/ ****************************************************************************/
...@@ -471,17 +301,17 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data ...@@ -471,17 +301,17 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data
hw->left = (buf[0] & 0x01) ? 1 : 0; hw->left = (buf[0] & 0x01) ? 1 : 0;
hw->right = (buf[0] & 0x02) ? 1 : 0; hw->right = (buf[0] & 0x02) ? 1 : 0;
if (SYN_CAP_EXTENDED(priv->capabilities) &&
(SYN_CAP_FOUR_BUTTON(priv->capabilities))) { if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
hw->up = ((buf[3] & 0x01)) ? 1 : 0; hw->middle = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
if (hw->left)
hw->up = !hw->up; if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
hw->down = ((buf[3] & 0x02)) ? 1 : 0; hw->up = ((buf[0] ^ buf[3]) & 0x01) ? 1 : 0;
if (hw->right) hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0;
hw->down = !hw->down;
} }
if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) && if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
((buf[3] & 2) ? !hw->right : hw->right)) { ((buf[0] ^ buf[3]) & 0x02)) {
switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) { switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
default: default:
/* /*
...@@ -490,17 +320,17 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data ...@@ -490,17 +320,17 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data
*/ */
break; break;
case 8: case 8:
hw->b7 = ((buf[5] & 0x08)) ? 1 : 0; hw->ext_buttons |= ((buf[5] & 0x08)) ? 0x80 : 0;
hw->b6 = ((buf[4] & 0x08)) ? 1 : 0; hw->ext_buttons |= ((buf[4] & 0x08)) ? 0x40 : 0;
case 6: case 6:
hw->b5 = ((buf[5] & 0x04)) ? 1 : 0; hw->ext_buttons |= ((buf[5] & 0x04)) ? 0x20 : 0;
hw->b4 = ((buf[4] & 0x04)) ? 1 : 0; hw->ext_buttons |= ((buf[4] & 0x04)) ? 0x10 : 0;
case 4: case 4:
hw->b3 = ((buf[5] & 0x02)) ? 1 : 0; hw->ext_buttons |= ((buf[5] & 0x02)) ? 0x08 : 0;
hw->b2 = ((buf[4] & 0x02)) ? 1 : 0; hw->ext_buttons |= ((buf[4] & 0x02)) ? 0x04 : 0;
case 2: case 2:
hw->b1 = ((buf[5] & 0x01)) ? 1 : 0; hw->ext_buttons |= ((buf[5] & 0x01)) ? 0x02 : 0;
hw->b0 = ((buf[4] & 0x01)) ? 1 : 0; hw->ext_buttons |= ((buf[4] & 0x01)) ? 0x01 : 0;
} }
} }
} else { } else {
...@@ -525,6 +355,7 @@ static void synaptics_process_packet(struct psmouse *psmouse) ...@@ -525,6 +355,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
struct synaptics_hw_state hw; struct synaptics_hw_state hw;
int num_fingers; int num_fingers;
int finger_width; int finger_width;
int i;
synaptics_parse_hw_state(psmouse->packet, priv, &hw); synaptics_parse_hw_state(psmouse->packet, priv, &hw);
...@@ -570,32 +401,20 @@ static void synaptics_process_packet(struct psmouse *psmouse) ...@@ -570,32 +401,20 @@ static void synaptics_process_packet(struct psmouse *psmouse)
input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2); input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3); input_report_key(dev, BTN_TOOL_TRIPLETAP, num_fingers == 3);
input_report_key(dev, BTN_LEFT, hw.left); input_report_key(dev, BTN_LEFT, hw.left);
input_report_key(dev, BTN_RIGHT, hw.right); input_report_key(dev, BTN_RIGHT, hw.right);
input_report_key(dev, BTN_FORWARD, hw.up);
input_report_key(dev, BTN_BACK, hw.down); if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) input_report_key(dev, BTN_MIDDLE, hw.middle);
switch(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
default: if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
/* input_report_key(dev, BTN_FORWARD, hw.up);
* if nExtBtn is greater than 8 it should be considered input_report_key(dev, BTN_BACK, hw.down);
* invalid and treated as 0 }
*/
break; for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
case 8: input_report_key(dev, BTN_0 + i, hw.ext_buttons & (1 << i));
input_report_key(dev, BTN_7, hw.b7);
input_report_key(dev, BTN_6, hw.b6);
case 6:
input_report_key(dev, BTN_5, hw.b5);
input_report_key(dev, BTN_4, hw.b4);
case 4:
input_report_key(dev, BTN_3, hw.b3);
input_report_key(dev, BTN_2, hw.b2);
case 2:
input_report_key(dev, BTN_1, hw.b1);
input_report_key(dev, BTN_0, hw.b0);
break;
}
input_sync(dev); input_sync(dev);
} }
...@@ -607,6 +426,9 @@ static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned cha ...@@ -607,6 +426,9 @@ static int synaptics_validate_byte(unsigned char packet[], int idx, unsigned cha
static unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 }; static unsigned char oldabs_mask[] = { 0xC0, 0x60, 0x00, 0xC0, 0x60 };
static unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 }; static unsigned char oldabs_rslt[] = { 0xC0, 0x00, 0x00, 0x80, 0x00 };
if (idx < 0 || idx > 4)
return 0;
switch (pkt_type) { switch (pkt_type) {
case SYN_NEWABS: case SYN_NEWABS:
case SYN_NEWABS_RELAXED: case SYN_NEWABS_RELAXED:
...@@ -637,7 +459,7 @@ static unsigned char synaptics_detect_pkt_type(struct psmouse *psmouse) ...@@ -637,7 +459,7 @@ static unsigned char synaptics_detect_pkt_type(struct psmouse *psmouse)
return SYN_NEWABS_STRICT; return SYN_NEWABS_STRICT;
} }
void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs) static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
{ {
struct input_dev *dev = &psmouse->dev; struct input_dev *dev = &psmouse->dev;
struct synaptics_data *priv = psmouse->private; struct synaptics_data *priv = psmouse->private;
...@@ -645,11 +467,6 @@ void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs) ...@@ -645,11 +467,6 @@ void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
input_regs(dev, regs); input_regs(dev, regs);
if (psmouse->pktcnt >= 6) { /* Full packet received */ if (psmouse->pktcnt >= 6) { /* Full packet received */
if (priv->out_of_sync) {
priv->out_of_sync = 0;
printk(KERN_NOTICE "Synaptics driver resynced.\n");
}
if (unlikely(priv->pkt_type == SYN_NEWABS)) if (unlikely(priv->pkt_type == SYN_NEWABS))
priv->pkt_type = synaptics_detect_pkt_type(psmouse); priv->pkt_type = synaptics_detect_pkt_type(psmouse);
...@@ -657,16 +474,142 @@ void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs) ...@@ -657,16 +474,142 @@ void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
synaptics_pass_pt_packet(&psmouse->ptport->serio, psmouse->packet); synaptics_pass_pt_packet(&psmouse->ptport->serio, psmouse->packet);
else else
synaptics_process_packet(psmouse); synaptics_process_packet(psmouse);
psmouse->pktcnt = 0;
return PSMOUSE_FULL_PACKET;
} else if (psmouse->pktcnt && }
!synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type)) {
printk(KERN_WARNING "Synaptics driver lost sync at byte %d\n", psmouse->pktcnt); return synaptics_validate_byte(psmouse->packet, psmouse->pktcnt - 1, priv->pkt_type) ?
psmouse->pktcnt = 0; PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA;
if (++priv->out_of_sync == psmouse_resetafter) { }
psmouse->state = PSMOUSE_IGNORE;
printk(KERN_NOTICE "synaptics: issuing reconnect request\n"); /*****************************************************************************
serio_reconnect(psmouse->serio); * Driver initialization/cleanup functions
} ****************************************************************************/
static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
{
int i;
set_bit(EV_ABS, dev->evbit);
input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
set_bit(ABS_TOOL_WIDTH, dev->absbit);
set_bit(EV_KEY, dev->evbit);
set_bit(BTN_TOUCH, dev->keybit);
set_bit(BTN_TOOL_FINGER, dev->keybit);
set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
set_bit(BTN_LEFT, dev->keybit);
set_bit(BTN_RIGHT, dev->keybit);
if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
set_bit(BTN_MIDDLE, dev->keybit);
if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) {
set_bit(BTN_FORWARD, dev->keybit);
set_bit(BTN_BACK, dev->keybit);
}
for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
set_bit(BTN_0 + i, dev->keybit);
clear_bit(EV_REL, dev->evbit);
clear_bit(REL_X, dev->relbit);
clear_bit(REL_Y, dev->relbit);
}
void synaptics_reset(struct psmouse *psmouse)
{
/* reset touchpad back to relative mode, gestures enabled */
synaptics_mode_cmd(psmouse, 0);
}
static void synaptics_disconnect(struct psmouse *psmouse)
{
synaptics_reset(psmouse);
kfree(psmouse->private);
}
static int synaptics_reconnect(struct psmouse *psmouse)
{
struct synaptics_data *priv = psmouse->private;
struct synaptics_data old_priv = *priv;
if (!synaptics_detect(psmouse))
return -1;
if (synaptics_query_hardware(psmouse)) {
printk(KERN_ERR "Unable to query Synaptics hardware.\n");
return -1;
}
if (old_priv.identity != priv->identity ||
old_priv.model_id != priv->model_id ||
old_priv.capabilities != priv->capabilities ||
old_priv.ext_cap != priv->ext_cap)
return -1;
if (synaptics_set_mode(psmouse, 0)) {
printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
return -1;
}
return 0;
}
int synaptics_detect(struct psmouse *psmouse)
{
unsigned char param[4];
param[0] = 0;
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_SETRES);
psmouse_command(psmouse, param, PSMOUSE_CMD_GETINFO);
return param[1] == 0x47;
}
int synaptics_init(struct psmouse *psmouse)
{
struct synaptics_data *priv;
psmouse->private = priv = kmalloc(sizeof(struct synaptics_data), GFP_KERNEL);
if (!priv)
return -1;
memset(priv, 0, sizeof(struct synaptics_data));
if (synaptics_query_hardware(psmouse)) {
printk(KERN_ERR "Unable to query Synaptics hardware.\n");
goto init_fail;
}
if (synaptics_set_mode(psmouse, 0)) {
printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
goto init_fail;
} }
priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
if (SYN_CAP_PASS_THROUGH(priv->capabilities))
synaptics_pt_create(psmouse);
print_ident(priv);
set_input_params(&psmouse->dev, priv);
psmouse->protocol_handler = synaptics_process_byte;
psmouse->disconnect = synaptics_disconnect;
psmouse->reconnect = synaptics_reconnect;
return 0;
init_fail:
kfree(priv);
return -1;
} }
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#ifndef _SYNAPTICS_H #ifndef _SYNAPTICS_H
#define _SYNAPTICS_H #define _SYNAPTICS_H
extern void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs);
extern int synaptics_detect(struct psmouse *psmouse); extern int synaptics_detect(struct psmouse *psmouse);
extern int synaptics_init(struct psmouse *psmouse); extern int synaptics_init(struct psmouse *psmouse);
extern void synaptics_reset(struct psmouse *psmouse); extern void synaptics_reset(struct psmouse *psmouse);
...@@ -44,13 +43,14 @@ extern void synaptics_reset(struct psmouse *psmouse); ...@@ -44,13 +43,14 @@ extern void synaptics_reset(struct psmouse *psmouse);
/* synaptics capability bits */ /* synaptics capability bits */
#define SYN_CAP_EXTENDED(c) ((c) & (1 << 23)) #define SYN_CAP_EXTENDED(c) ((c) & (1 << 23))
#define SYN_CAP_MIDDLE_BUTTON(c) ((c) & (1 << 18))
#define SYN_CAP_PASS_THROUGH(c) ((c) & (1 << 7)) #define SYN_CAP_PASS_THROUGH(c) ((c) & (1 << 7))
#define SYN_CAP_SLEEP(c) ((c) & (1 << 4)) #define SYN_CAP_SLEEP(c) ((c) & (1 << 4))
#define SYN_CAP_FOUR_BUTTON(c) ((c) & (1 << 3)) #define SYN_CAP_FOUR_BUTTON(c) ((c) & (1 << 3))
#define SYN_CAP_MULTIFINGER(c) ((c) & (1 << 1)) #define SYN_CAP_MULTIFINGER(c) ((c) & (1 << 1))
#define SYN_CAP_PALMDETECT(c) ((c) & (1 << 0)) #define SYN_CAP_PALMDETECT(c) ((c) & (1 << 0))
#define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47) #define SYN_CAP_VALID(c) ((((c) & 0x00ff00) >> 8) == 0x47)
#define SYN_EXT_CAP_REQUESTS(c) ((((c) & 0x700000) >> 20) == 1) #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20)
#define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12)
/* synaptics modes query bits */ /* synaptics modes query bits */
...@@ -86,18 +86,12 @@ struct synaptics_hw_state { ...@@ -86,18 +86,12 @@ struct synaptics_hw_state {
int y; int y;
int z; int z;
int w; int w;
int left; unsigned int left:1;
int right; unsigned int right:1;
int up; unsigned int middle:1;
int down; unsigned int up:1;
int b0; unsigned int down:1;
int b1; unsigned char ext_buttons;
int b2;
int b3;
int b4;
int b5;
int b6;
int b7;
}; };
struct synaptics_data { struct synaptics_data {
...@@ -108,7 +102,6 @@ struct synaptics_data { ...@@ -108,7 +102,6 @@ struct synaptics_data {
unsigned long int identity; /* Identification */ unsigned long int identity; /* Identification */
/* Data for normal processing */ /* Data for normal processing */
unsigned int out_of_sync; /* # of packets out of sync */
int old_w; /* Previous w value */ int old_w; /* Previous w value */
unsigned char pkt_type; /* packet type - old, new, etc */ unsigned char pkt_type; /* packet type - old, new, etc */
}; };
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* Input driver to ExplorerPS/2 device driver module. * Input driver to ExplorerPS/2 device driver module.
* *
* Copyright (c) 1999-2002 Vojtech Pavlik * Copyright (c) 1999-2002 Vojtech Pavlik
* Copyright (c) 2004 Dmitry Torokhov
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published by * it under the terms of the GNU General Public License version 2 as published by
...@@ -47,15 +48,24 @@ static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y; ...@@ -47,15 +48,24 @@ static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y;
module_param(yres, uint, 0); module_param(yres, uint, 0);
MODULE_PARM_DESC(yres, "Vertical screen resolution"); MODULE_PARM_DESC(yres, "Vertical screen resolution");
struct mousedev_motion {
int dx, dy, dz;
};
struct mousedev { struct mousedev {
int exist; int exist;
int open; int open;
int minor; int minor;
int misc;
char name[16]; char name[16];
wait_queue_head_t wait; wait_queue_head_t wait;
struct list_head list; struct list_head list;
struct input_handle handle; struct input_handle handle;
struct mousedev_motion packet;
unsigned long buttons;
unsigned int pkt_count;
int old_x[4], old_y[4];
unsigned int touch;
}; };
struct mousedev_list { struct mousedev_list {
...@@ -63,13 +73,10 @@ struct mousedev_list { ...@@ -63,13 +73,10 @@ struct mousedev_list {
struct mousedev *mousedev; struct mousedev *mousedev;
struct list_head node; struct list_head node;
int dx, dy, dz; int dx, dy, dz;
int old_x[4], old_y[4];
unsigned long buttons; unsigned long buttons;
signed char ps2[6]; signed char ps2[6];
unsigned char ready, buffer, bufsiz; unsigned char ready, buffer, bufsiz;
unsigned char mode, imexseq, impsseq; unsigned char mode, imexseq, impsseq;
unsigned int pkt_count;
unsigned char touch;
}; };
#define MOUSEDEV_SEQ_LEN 6 #define MOUSEDEV_SEQ_LEN 6
...@@ -82,135 +89,157 @@ static struct input_handler mousedev_handler; ...@@ -82,135 +89,157 @@ static struct input_handler mousedev_handler;
static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
static struct mousedev mousedev_mix; static struct mousedev mousedev_mix;
#define fx(i) (list->old_x[(list->pkt_count - (i)) & 03]) #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
#define fy(i) (list->old_y[(list->pkt_count - (i)) & 03]) #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
static void mousedev_abs_event(struct input_handle *handle, struct mousedev_list *list, unsigned int code, int value) static void mousedev_touchpad_event(struct mousedev *mousedev, unsigned int code, int value)
{ {
int size; if (mousedev->touch) {
int touchpad; switch (code) {
case ABS_X:
fx(0) = value;
if (mousedev->pkt_count >= 2)
mousedev->packet.dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
break;
/* Ignore joysticks */ case ABS_Y:
if (test_bit(BTN_TRIGGER, handle->dev->keybit)) fy(0) = value;
return; if (mousedev->pkt_count >= 2)
mousedev->packet.dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
break;
}
}
}
touchpad = test_bit(BTN_TOOL_FINGER, handle->dev->keybit); static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value)
{
int size;
switch (code) { switch (code) {
case ABS_X: case ABS_X:
if (touchpad) { size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
if (list->touch) { if (size == 0) size = xres;
fx(0) = value; mousedev->packet.dx = (value * xres - mousedev->old_x[0]) / size;
if (list->pkt_count >= 2) mousedev->old_x[0] = mousedev->packet.dx * size;
list->dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
}
} else {
size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
if (size == 0) size = xres;
list->dx += (value * xres - list->old_x[0]) / size;
list->old_x[0] += list->dx * size;
}
break; break;
case ABS_Y: case ABS_Y:
if (touchpad) { size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y];
if (list->touch) { if (size == 0) size = yres;
fy(0) = value; mousedev->packet.dy = (value * yres - mousedev->old_y[0]) / size;
if (list->pkt_count >= 2) mousedev->old_y[0] = mousedev->packet.dy * size;
list->dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
}
} else {
size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
if (size == 0) size = yres;
list->dy -= (value * yres - list->old_y[0]) / size;
list->old_y[0] -= list->dy * size;
}
break; break;
} }
} }
static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) static void mousedev_rel_event(struct mousedev *mousedev, unsigned int code, int value)
{
switch (code) {
case REL_X: mousedev->packet.dx += value; break;
case REL_Y: mousedev->packet.dy -= value; break;
case REL_WHEEL: mousedev->packet.dz -= value; break;
}
}
static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int value)
{
int index;
switch (code) {
case BTN_TOUCH:
case BTN_0:
case BTN_FORWARD:
case BTN_LEFT: index = 0; break;
case BTN_STYLUS:
case BTN_1:
case BTN_RIGHT: index = 1; break;
case BTN_2:
case BTN_STYLUS2:
case BTN_MIDDLE: index = 2; break;
case BTN_3:
case BTN_BACK:
case BTN_SIDE: index = 3; break;
case BTN_4:
case BTN_EXTRA: index = 4; break;
default: return;
}
if (value) {
set_bit(index, &mousedev->buttons);
set_bit(index, &mousedev_mix.buttons);
} else {
clear_bit(index, &mousedev->buttons);
clear_bit(index, &mousedev_mix.buttons);
}
}
static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_motion *packet)
{ {
struct mousedev *mousedevs[3] = { handle->private, &mousedev_mix, NULL };
struct mousedev **mousedev = mousedevs;
struct mousedev_list *list; struct mousedev_list *list;
int index, wake;
list_for_each_entry(list, &mousedev->list, node) {
while (*mousedev) { list->dx += packet->dx;
list->dy += packet->dy;
wake = 0; list->dz += packet->dz;
list->buttons = mousedev->buttons;
list_for_each_entry(list, &(*mousedev)->list, node) list->ready = 1;
switch (type) { kill_fasync(&list->fasync, SIGIO, POLL_IN);
case EV_ABS: }
mousedev_abs_event(handle, list, code, value);
break; wake_up_interruptible(&mousedev->wait);
}
case EV_REL:
switch (code) { static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
case REL_X: list->dx += value; break; {
case REL_Y: list->dy -= value; break; struct mousedev *mousedev = handle->private;
case REL_WHEEL: if (list->mode) list->dz -= value; break;
} switch (type) {
break; case EV_ABS:
/* Ignore joysticks */
case EV_KEY: if (test_bit(BTN_TRIGGER, handle->dev->keybit))
if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) { return;
/* Handle touchpad data */
list->touch = value; if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
if (!list->touch) mousedev_touchpad_event(mousedev, code, value);
list->pkt_count = 0; else
break; mousedev_abs_event(handle->dev, mousedev, code, value);
}
break;
switch (code) {
case BTN_TOUCH: case EV_REL:
case BTN_0: mousedev_rel_event(mousedev, code, value);
case BTN_FORWARD: break;
case BTN_LEFT: index = 0; break;
case BTN_4: case EV_KEY:
case BTN_EXTRA: if (list->mode == 2) { index = 4; break; } if (value != 2) {
case BTN_STYLUS: if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
case BTN_1: /* Handle touchpad data */
case BTN_RIGHT: index = 1; break; mousedev->touch = value;
case BTN_3: if (!mousedev->touch)
case BTN_BACK: mousedev->pkt_count = 0;
case BTN_SIDE: if (list->mode == 2) { index = 3; break; } }
case BTN_2: else
case BTN_STYLUS2: mousedev_key_event(mousedev, code, value);
case BTN_MIDDLE: index = 2; break;
default: return;
}
switch (value) {
case 0: clear_bit(index, &list->buttons); break;
case 1: set_bit(index, &list->buttons); break;
case 2: return;
}
break;
case EV_SYN:
switch (code) {
case SYN_REPORT:
if (list->touch) {
list->pkt_count++;
/* Input system eats duplicate events,
* but we need all of them to do correct
* averaging so apply present one forward
*/
fx(0) = fx(1);
fy(0) = fy(1);
}
list->ready = 1;
kill_fasync(&list->fasync, SIGIO, POLL_IN);
wake = 1;
break;
}
} }
break;
case EV_SYN:
if (code == SYN_REPORT) {
if (mousedev->touch) {
mousedev->pkt_count++;
/* Input system eats duplicate events, but we need all of them
* to do correct averaging so apply present one forward
*/
fx(0) = fx(1);
fy(0) = fy(1);
}
if (wake) mousedev_notify_readers(mousedev, &mousedev->packet);
wake_up_interruptible(&((*mousedev)->wait)); mousedev_notify_readers(&mousedev_mix, &mousedev->packet);
mousedev++; memset(&mousedev->packet, 0, sizeof(struct mousedev_motion));
}
break;
} }
} }
...@@ -267,7 +296,7 @@ static int mousedev_release(struct inode * inode, struct file * file) ...@@ -267,7 +296,7 @@ static int mousedev_release(struct inode * inode, struct file * file)
mousedev_free(list->mousedev); mousedev_free(list->mousedev);
} }
} }
kfree(list); kfree(list);
return 0; return 0;
} }
...@@ -301,11 +330,11 @@ static int mousedev_open(struct inode * inode, struct file * file) ...@@ -301,11 +330,11 @@ static int mousedev_open(struct inode * inode, struct file * file)
if (list->mousedev->minor == MOUSEDEV_MIX) { if (list->mousedev->minor == MOUSEDEV_MIX) {
list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { list_for_each_entry(handle, &mousedev_handler.h_list, h_node) {
mousedev = handle->private; mousedev = handle->private;
if (!mousedev->open && mousedev->exist) if (!mousedev->open && mousedev->exist)
input_open_device(handle); input_open_device(handle);
} }
} else } else
if (!mousedev_mix.open && list->mousedev->exist) if (!mousedev_mix.open && list->mousedev->exist)
input_open_device(&list->mousedev->handle); input_open_device(&list->mousedev->handle);
} }
...@@ -326,8 +355,10 @@ static void mousedev_packet(struct mousedev_list *list, unsigned char off) ...@@ -326,8 +355,10 @@ static void mousedev_packet(struct mousedev_list *list, unsigned char off)
list->dz -= list->ps2[off + 3]; list->dz -= list->ps2[off + 3];
list->ps2[off + 3] = (list->ps2[off + 3] & 0x0f) | ((list->buttons & 0x18) << 1); list->ps2[off + 3] = (list->ps2[off + 3] & 0x0f) | ((list->buttons & 0x18) << 1);
list->bufsiz++; list->bufsiz++;
} else {
list->ps2[off] |= ((list->buttons & 0x10) >> 3) | ((list->buttons & 0x08) >> 1);
} }
if (list->mode == 1) { if (list->mode == 1) {
list->ps2[off + 3] = (list->dz > 127 ? 127 : (list->dz < -127 ? -127 : list->dz)); list->ps2[off + 3] = (list->dz > 127 ? 127 : (list->dz < -127 ? -127 : list->dz));
list->dz -= list->ps2[off + 3]; list->dz -= list->ps2[off + 3];
...@@ -391,9 +422,9 @@ static ssize_t mousedev_write(struct file * file, const char __user * buffer, si ...@@ -391,9 +422,9 @@ static ssize_t mousedev_write(struct file * file, const char __user * buffer, si
list->impsseq = 0; list->impsseq = 0;
list->imexseq = 0; list->imexseq = 0;
list->mode = 0; list->mode = 0;
list->ps2[0] = 0xaa; list->ps2[1] = 0xaa;
list->ps2[1] = 0x00; list->ps2[2] = 0x00;
list->bufsiz = 2; list->bufsiz = 3;
break; break;
} }
...@@ -403,7 +434,7 @@ static ssize_t mousedev_write(struct file * file, const char __user * buffer, si ...@@ -403,7 +434,7 @@ static ssize_t mousedev_write(struct file * file, const char __user * buffer, si
kill_fasync(&list->fasync, SIGIO, POLL_IN); kill_fasync(&list->fasync, SIGIO, POLL_IN);
wake_up_interruptible(&list->mousedev->wait); wake_up_interruptible(&list->mousedev->wait);
return count; return count;
} }
...@@ -431,7 +462,7 @@ static ssize_t mousedev_read(struct file * file, char __user * buffer, size_t co ...@@ -431,7 +462,7 @@ static ssize_t mousedev_read(struct file * file, char __user * buffer, size_t co
if (copy_to_user(buffer, list->ps2 + list->bufsiz - list->buffer - count, count)) if (copy_to_user(buffer, list->ps2 + list->bufsiz - list->buffer - count, count))
return -EFAULT; return -EFAULT;
return count; return count;
} }
/* No kernel lock - fine */ /* No kernel lock - fine */
...@@ -487,7 +518,7 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru ...@@ -487,7 +518,7 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru
devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
S_IFCHR|S_IRUGO|S_IWUSR, "input/mouse%d", minor); S_IFCHR|S_IRUGO|S_IWUSR, "input/mouse%d", minor);
class_simple_device_add(input_class, class_simple_device_add(input_class,
MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
dev->dev, "mouse%d", minor); dev->dev, "mouse%d", minor);
...@@ -538,7 +569,7 @@ static struct input_device_id mousedev_ids[] = { ...@@ -538,7 +569,7 @@ static struct input_device_id mousedev_ids[] = {
}; };
MODULE_DEVICE_TABLE(input, mousedev_ids); MODULE_DEVICE_TABLE(input, mousedev_ids);
static struct input_handler mousedev_handler = { static struct input_handler mousedev_handler = {
.event = mousedev_event, .event = mousedev_event,
.connect = mousedev_connect, .connect = mousedev_connect,
...@@ -553,6 +584,7 @@ static struct input_handler mousedev_handler = { ...@@ -553,6 +584,7 @@ static struct input_handler mousedev_handler = {
static struct miscdevice psaux_mouse = { static struct miscdevice psaux_mouse = {
PSMOUSE_MINOR, "psaux", &mousedev_fops PSMOUSE_MINOR, "psaux", &mousedev_fops
}; };
static int psaux_registered;
#endif #endif
static int __init mousedev_init(void) static int __init mousedev_init(void)
...@@ -572,7 +604,7 @@ static int __init mousedev_init(void) ...@@ -572,7 +604,7 @@ static int __init mousedev_init(void)
NULL, "mice"); NULL, "mice");
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
if (!(mousedev_mix.misc = !misc_register(&psaux_mouse))) if (!(psaux_registered = !misc_register(&psaux_mouse)))
printk(KERN_WARNING "mice: could not misc_register the device\n"); printk(KERN_WARNING "mice: could not misc_register the device\n");
#endif #endif
...@@ -584,7 +616,7 @@ static int __init mousedev_init(void) ...@@ -584,7 +616,7 @@ static int __init mousedev_init(void)
static void __exit mousedev_exit(void) static void __exit mousedev_exit(void)
{ {
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
if (mousedev_mix.misc) if (psaux_registered)
misc_deregister(&psaux_mouse); misc_deregister(&psaux_mouse);
#endif #endif
devfs_remove("input/mice"); devfs_remove("input/mice");
......
/* /*
* $Id: power.c,v 1.10 2001/09/25 09:17:15 vojtech Exp $ * $Id: power.c,v 1.10 2001/09/25 09:17:15 vojtech Exp $
* *
* Copyright (c) 2001 "Crazy" James Simmons * Copyright (c) 2001 "Crazy" James Simmons
* *
* Input driver Power Management. * Input driver Power Management.
* *
...@@ -51,7 +51,7 @@ static void suspend_button_task_handler(void *data) ...@@ -51,7 +51,7 @@ static void suspend_button_task_handler(void *data)
static DECLARE_WORK(suspend_button_task, suspend_button_task_handler, NULL); static DECLARE_WORK(suspend_button_task, suspend_button_task_handler, NULL);
static void power_event(struct input_handle *handle, unsigned int type, static void power_event(struct input_handle *handle, unsigned int type,
unsigned int code, int down) unsigned int code, int down)
{ {
struct input_dev *dev = handle->dev; struct input_dev *dev = handle->dev;
...@@ -73,7 +73,7 @@ static void power_event(struct input_handle *handle, unsigned int type, ...@@ -73,7 +73,7 @@ static void power_event(struct input_handle *handle, unsigned int type,
case KEY_POWER: case KEY_POWER:
/* Hum power down the machine. */ /* Hum power down the machine. */
break; break;
default: default:
return; return;
} }
} else { } else {
...@@ -83,9 +83,9 @@ static void power_event(struct input_handle *handle, unsigned int type, ...@@ -83,9 +83,9 @@ static void power_event(struct input_handle *handle, unsigned int type,
/* This is risky. See pm.h for details. */ /* This is risky. See pm.h for details. */
if (dev->state != PM_RESUME) if (dev->state != PM_RESUME)
dev->state = PM_RESUME; dev->state = PM_RESUME;
else else
dev->state = PM_SUSPEND; dev->state = PM_SUSPEND;
pm_send(dev->pm_dev, dev->state, dev); pm_send(dev->pm_dev, dev->state, dev);
break; break;
case KEY_POWER: case KEY_POWER:
/* Turn the input device off completely ? */ /* Turn the input device off completely ? */
...@@ -97,14 +97,14 @@ static void power_event(struct input_handle *handle, unsigned int type, ...@@ -97,14 +97,14 @@ static void power_event(struct input_handle *handle, unsigned int type,
return; return;
} }
static struct input_handle *power_connect(struct input_handler *handler, static struct input_handle *power_connect(struct input_handler *handler,
struct input_dev *dev, struct input_dev *dev,
struct input_device_id *id) struct input_device_id *id)
{ {
struct input_handle *handle; struct input_handle *handle;
if (!test_bit(EV_KEY, dev->evbit) || !test_bit(EV_PWR, dev->evbit)) if (!test_bit(EV_KEY, dev->evbit) || !test_bit(EV_PWR, dev->evbit))
return NULL; return NULL;
if (!test_bit(KEY_SUSPEND, dev->keybit) || (!test_bit(KEY_POWER, dev->keybit))) if (!test_bit(KEY_SUSPEND, dev->keybit) || (!test_bit(KEY_POWER, dev->keybit)))
return NULL; return NULL;
...@@ -133,21 +133,21 @@ static struct input_device_id power_ids[] = { ...@@ -133,21 +133,21 @@ static struct input_device_id power_ids[] = {
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT(EV_KEY) }, .evbit = { BIT(EV_KEY) },
.keybit = { [LONG(KEY_SUSPEND)] = BIT(KEY_SUSPEND) } .keybit = { [LONG(KEY_SUSPEND)] = BIT(KEY_SUSPEND) }
}, },
{ {
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT(EV_KEY) }, .evbit = { BIT(EV_KEY) },
.keybit = { [LONG(KEY_POWER)] = BIT(KEY_POWER) } .keybit = { [LONG(KEY_POWER)] = BIT(KEY_POWER) }
}, },
{ {
.flags = INPUT_DEVICE_ID_MATCH_EVBIT, .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
.evbit = { BIT(EV_PWR) }, .evbit = { BIT(EV_PWR) },
}, },
{ }, /* Terminating entry */ { }, /* Terminating entry */
}; };
MODULE_DEVICE_TABLE(input, power_ids); MODULE_DEVICE_TABLE(input, power_ids);
static struct input_handler power_handler = { static struct input_handler power_handler = {
.event = power_event, .event = power_event,
.connect = power_connect, .connect = power_connect,
...@@ -172,3 +172,4 @@ module_exit(power_exit); ...@@ -172,3 +172,4 @@ module_exit(power_exit);
MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>"); MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
MODULE_DESCRIPTION("Input Power Management driver"); MODULE_DESCRIPTION("Input Power Management driver");
MODULE_LICENSE("GPL");
...@@ -42,8 +42,8 @@ MODULE_LICENSE("GPL"); ...@@ -42,8 +42,8 @@ MODULE_LICENSE("GPL");
* Register numbers. * Register numbers.
*/ */
#define KBD98_COMMAND_REG 0x43 #define KBD98_COMMAND_REG 0x43
#define KBD98_STATUS_REG 0x43 #define KBD98_STATUS_REG 0x43
#define KBD98_DATA_REG 0x41 #define KBD98_DATA_REG 0x41
spinlock_t kbd98io_lock = SPIN_LOCK_UNLOCKED; spinlock_t kbd98io_lock = SPIN_LOCK_UNLOCKED;
...@@ -51,7 +51,7 @@ spinlock_t kbd98io_lock = SPIN_LOCK_UNLOCKED; ...@@ -51,7 +51,7 @@ spinlock_t kbd98io_lock = SPIN_LOCK_UNLOCKED;
static struct serio kbd98_port; static struct serio kbd98_port;
extern struct pt_regs *kbd_pt_regs; extern struct pt_regs *kbd_pt_regs;
static void kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs); static irqreturn_t kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs);
/* /*
* kbd98_flush() flushes all data that may be in the keyboard buffers * kbd98_flush() flushes all data that may be in the keyboard buffers
...@@ -143,7 +143,7 @@ static struct serio kbd98_port = ...@@ -143,7 +143,7 @@ static struct serio kbd98_port =
* to the upper layers. * to the upper layers.
*/ */
static void kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{ {
unsigned long flags; unsigned long flags;
unsigned char data; unsigned char data;
...@@ -154,6 +154,7 @@ static void kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -154,6 +154,7 @@ static void kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs)
spin_unlock_irqrestore(&kbd98io_lock, flags); spin_unlock_irqrestore(&kbd98io_lock, flags);
serio_interrupt(&kbd98_port, data, 0, regs); serio_interrupt(&kbd98_port, data, 0, regs);
return IRQ_HANDLED;
} }
int __init kbd98io_init(void) int __init kbd98io_init(void)
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* This file is subject to the terms and conditions of the GNU General Public * This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* TODO: * TODO:
* - Dino testing (did HP ever shipped a machine on which this port * - Dino testing (did HP ever shipped a machine on which this port
* was usable/enabled ?) * was usable/enabled ?)
...@@ -44,7 +44,7 @@ MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl); ...@@ -44,7 +44,7 @@ MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
#define PFX "gscps2.c: " #define PFX "gscps2.c: "
/* /*
* Driver constants * Driver constants
*/ */
...@@ -222,7 +222,7 @@ static LIST_HEAD(ps2port_list); ...@@ -222,7 +222,7 @@ static LIST_HEAD(ps2port_list);
/** /**
* gscps2_interrupt() - Interruption service routine * gscps2_interrupt() - Interruption service routine
* *
* This function reads received PS/2 bytes and processes them on * This function reads received PS/2 bytes and processes them on
* all interfaces. * all interfaces.
* The problematic part here is, that the keyboard and mouse PS/2 port * The problematic part here is, that the keyboard and mouse PS/2 port
* share the same interrupt and it's not possible to send data if any * share the same interrupt and it's not possible to send data if any
...@@ -240,9 +240,9 @@ static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs) ...@@ -240,9 +240,9 @@ static irqreturn_t gscps2_interrupt(int irq, void *dev, struct pt_regs *regs)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&ps2port->lock, flags); spin_lock_irqsave(&ps2port->lock, flags);
while ( (ps2port->buffer[ps2port->append].str = while ( (ps2port->buffer[ps2port->append].str =
gscps2_readb_status(ps2port->addr)) & GSC_STAT_RBNE ) { gscps2_readb_status(ps2port->addr)) & GSC_STAT_RBNE ) {
ps2port->buffer[ps2port->append].data = ps2port->buffer[ps2port->append].data =
gscps2_readb_input(ps2port->addr); gscps2_readb_input(ps2port->addr);
ps2port->append = ((ps2port->append+1) & BUFFER_SIZE); ps2port->append = ((ps2port->append+1) & BUFFER_SIZE);
} }
...@@ -349,7 +349,7 @@ static int __init gscps2_probe(struct parisc_device *dev) ...@@ -349,7 +349,7 @@ static int __init gscps2_probe(struct parisc_device *dev)
if (!dev->irq) if (!dev->irq)
return -ENODEV; return -ENODEV;
/* Offset for DINO PS/2. Works with LASI even */ /* Offset for DINO PS/2. Works with LASI even */
if (dev->id.sversion == 0x96) if (dev->id.sversion == 0x96)
hpa += GSC_DINO_OFFSET; hpa += GSC_DINO_OFFSET;
...@@ -368,7 +368,7 @@ static int __init gscps2_probe(struct parisc_device *dev) ...@@ -368,7 +368,7 @@ static int __init gscps2_probe(struct parisc_device *dev)
gscps2_reset(ps2port); gscps2_reset(ps2port);
ps2port->id = readb(ps2port->addr+GSC_ID) & 0x0f; ps2port->id = readb(ps2port->addr+GSC_ID) & 0x0f;
snprintf(ps2port->name, sizeof(ps2port->name)-1, "%s %s", snprintf(ps2port->name, sizeof(ps2port->name)-1, "%s %s",
gscps2_serio_port.name, gscps2_serio_port.name,
(ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse" ); (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse" );
memcpy(&ps2port->port, &gscps2_serio_port, sizeof(gscps2_serio_port)); memcpy(&ps2port->port, &gscps2_serio_port, sizeof(gscps2_serio_port));
...@@ -401,9 +401,9 @@ static int __init gscps2_probe(struct parisc_device *dev) ...@@ -401,9 +401,9 @@ static int __init gscps2_probe(struct parisc_device *dev)
ps2port->port.phys); ps2port->port.phys);
serio_register_port(&ps2port->port); serio_register_port(&ps2port->port);
return 0; return 0;
fail: fail:
free_irq(dev->irq, ps2port); free_irq(dev->irq, ps2port);
...@@ -430,7 +430,7 @@ static int __devexit gscps2_remove(struct parisc_device *dev) ...@@ -430,7 +430,7 @@ static int __devexit gscps2_remove(struct parisc_device *dev)
list_del(&ps2port->node); list_del(&ps2port->node);
iounmap(ps2port->addr); iounmap(ps2port->addr);
#if 0 #if 0
release_mem_region(dev->hpa, GSC_STATUS + 4); release_mem_region(dev->hpa, GSC_STATUS + 4);
#endif #endif
dev_set_drvdata(&dev->dev, NULL); dev_set_drvdata(&dev->dev, NULL);
kfree(ps2port); kfree(ps2port);
...@@ -441,7 +441,7 @@ static int __devexit gscps2_remove(struct parisc_device *dev) ...@@ -441,7 +441,7 @@ static int __devexit gscps2_remove(struct parisc_device *dev)
static struct parisc_device_id gscps2_device_tbl[] = { static struct parisc_device_id gscps2_device_tbl[] = {
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 }, /* LASI PS/2 */ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 }, /* LASI PS/2 */
#ifdef DINO_TESTED #ifdef DINO_TESTED
{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, /* DINO PS/2 */ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, /* DINO PS/2 */
#endif #endif
{ 0, } /* 0 terminated list */ { 0, } /* 0 terminated list */
}; };
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* i8042 keyboard and mouse controller driver for Linux * i8042 keyboard and mouse controller driver for Linux
* *
* Copyright (c) 1999-2002 Vojtech Pavlik * Copyright (c) 1999-2002 Vojtech Pavlik
* Copyright (c) 2004 Dmitry Torokhov
*/ */
/* /*
...@@ -74,6 +75,14 @@ struct i8042_values { ...@@ -74,6 +75,14 @@ struct i8042_values {
unsigned char *phys; unsigned char *phys;
}; };
#define I8042_QUEUE_LEN 64
struct {
unsigned char str[I8042_QUEUE_LEN];
unsigned char data[I8042_QUEUE_LEN];
unsigned int read_pos;
unsigned int write_pos;
} i8042_buf;
static struct serio i8042_kbd_port; static struct serio i8042_kbd_port;
static struct serio i8042_aux_port; static struct serio i8042_aux_port;
static unsigned char i8042_initial_ctr; static unsigned char i8042_initial_ctr;
...@@ -82,7 +91,7 @@ static unsigned char i8042_mux_open; ...@@ -82,7 +91,7 @@ static unsigned char i8042_mux_open;
static unsigned char i8042_mux_present; static unsigned char i8042_mux_present;
static unsigned char i8042_sysdev_initialized; static unsigned char i8042_sysdev_initialized;
static struct pm_dev *i8042_pm_dev; static struct pm_dev *i8042_pm_dev;
struct timer_list i8042_timer; static struct timer_list i8042_timer;
/* /*
* Shared IRQ's require a device pointer, but this driver doesn't support * Shared IRQ's require a device pointer, but this driver doesn't support
...@@ -150,7 +159,7 @@ static int i8042_flush(void) ...@@ -150,7 +159,7 @@ static int i8042_flush(void)
*/ */
static int i8042_command(unsigned char *param, int command) static int i8042_command(unsigned char *param, int command)
{ {
unsigned long flags; unsigned long flags;
int retval = 0, i = 0; int retval = 0, i = 0;
...@@ -161,7 +170,7 @@ static int i8042_command(unsigned char *param, int command) ...@@ -161,7 +170,7 @@ static int i8042_command(unsigned char *param, int command)
dbg("%02x -> i8042 (command)", command & 0xff); dbg("%02x -> i8042 (command)", command & 0xff);
i8042_write_command(command & 0xff); i8042_write_command(command & 0xff);
} }
if (!retval) if (!retval)
for (i = 0; i < ((command >> 12) & 0xf); i++) { for (i = 0; i < ((command >> 12) & 0xf); i++) {
if ((retval = i8042_wait_write())) break; if ((retval = i8042_wait_write())) break;
...@@ -172,7 +181,7 @@ static int i8042_command(unsigned char *param, int command) ...@@ -172,7 +181,7 @@ static int i8042_command(unsigned char *param, int command)
if (!retval) if (!retval)
for (i = 0; i < ((command >> 8) & 0xf); i++) { for (i = 0; i < ((command >> 8) & 0xf); i++) {
if ((retval = i8042_wait_read())) break; if ((retval = i8042_wait_read())) break;
if (i8042_read_status() & I8042_STR_AUXDATA) if (i8042_read_status() & I8042_STR_AUXDATA)
param[i] = ~i8042_read_data(); param[i] = ~i8042_read_data();
else else
param[i] = i8042_read_data(); param[i] = i8042_read_data();
...@@ -374,77 +383,109 @@ static char i8042_mux_short[4][16]; ...@@ -374,77 +383,109 @@ static char i8042_mux_short[4][16];
static char i8042_mux_phys[4][32]; static char i8042_mux_phys[4][32];
/* /*
* i8042_interrupt() is the most important function in this driver - * i8042_handle_data() is the most important function in this driver -
* it handles the interrupts from the i8042, and sends incoming bytes * it processes data received by i8042_interrupt and sends it to the
* to the upper layers. * upper layers.
*/ */
static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs) static void i8042_handle_data(unsigned long notused)
{ {
unsigned long flags;
unsigned char str, data = 0; unsigned char str, data = 0;
unsigned int dfl; unsigned int dfl;
int ret;
mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD); /*
* No locking it required on i8042_buf as the tasklet is guaranteed
* to be serialized and if write_pos changes while comparing it with
* read_pos another run will be scheduled by i8042_interrupt.
*/
while (i8042_buf.read_pos != i8042_buf.write_pos) {
spin_lock_irqsave(&i8042_lock, flags); str = i8042_buf.str[i8042_buf.read_pos];
str = i8042_read_status(); data = i8042_buf.data[i8042_buf.read_pos];
if (str & I8042_STR_OBF)
data = i8042_read_data();
spin_unlock_irqrestore(&i8042_lock, flags);
if (~str & I8042_STR_OBF) { i8042_buf.read_pos++;
if (irq) dbg("Interrupt %d, without any data", irq); i8042_buf.read_pos %= I8042_QUEUE_LEN;
ret = 0;
goto out;
}
dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) | dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) |
((str & I8042_STR_TIMEOUT) ? SERIO_TIMEOUT : 0); ((str & I8042_STR_TIMEOUT) ? SERIO_TIMEOUT : 0);
if (i8042_mux_values[0].exists && (str & I8042_STR_AUXDATA)) { if (i8042_mux_values[0].exists && (str & I8042_STR_AUXDATA)) {
if (str & I8042_STR_MUXERR) { if (str & I8042_STR_MUXERR) {
switch (data) { switch (data) {
case 0xfd: case 0xfd:
case 0xfe: dfl = SERIO_TIMEOUT; break; case 0xfe: dfl = SERIO_TIMEOUT; break;
case 0xff: dfl = SERIO_PARITY; break; case 0xff: dfl = SERIO_PARITY; break;
} }
data = 0xfe; data = 0xfe;
} else dfl = 0; } else dfl = 0;
dbg("%02x <- i8042 (interrupt, aux%d, %d%s%s)", dbg("%02x <- i8042 (interrupt, aux%d, %d%s%s)",
data, (str >> 6), irq, data, (str >> 6), irq,
dfl & SERIO_PARITY ? ", bad parity" : "", dfl & SERIO_PARITY ? ", bad parity" : "",
dfl & SERIO_TIMEOUT ? ", timeout" : ""); dfl & SERIO_TIMEOUT ? ", timeout" : "");
serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl, regs); serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl, NULL);
} else {
goto irq_ret;
dbg("%02x <- i8042 (interrupt, %s, %d%s%s)",
data, (str & I8042_STR_AUXDATA) ? "aux" : "kbd", irq,
dfl & SERIO_PARITY ? ", bad parity" : "",
dfl & SERIO_TIMEOUT ? ", timeout" : "");
if (i8042_aux_values.exists && (str & I8042_STR_AUXDATA))
serio_interrupt(&i8042_aux_port, data, dfl, NULL);
else if (i8042_kbd_values.exists)
serio_interrupt(&i8042_kbd_port, data, dfl, NULL);
}
} }
}
dbg("%02x <- i8042 (interrupt, %s, %d%s%s)", DECLARE_TASKLET(i8042_tasklet, i8042_handle_data, 0);
data, (str & I8042_STR_AUXDATA) ? "aux" : "kbd", irq,
dfl & SERIO_PARITY ? ", bad parity" : "", /*
dfl & SERIO_TIMEOUT ? ", timeout" : ""); * i8042_interrupt() handles the interrupts from i8042 and schedules
* i8042_handle_data to process and pass received bytes to the upper
* layers.
*/
static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned long flags;
unsigned char str;
unsigned int n_bytes = 0;
mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
if (i8042_aux_values.exists && (str & I8042_STR_AUXDATA)) { spin_lock_irqsave(&i8042_lock, flags);
serio_interrupt(&i8042_aux_port, data, dfl, regs);
goto irq_ret; while ((str = i8042_read_status()) & I8042_STR_OBF) {
n_bytes++;
i8042_buf.str[i8042_buf.write_pos] = str;
i8042_buf.data[i8042_buf.write_pos] = i8042_read_data();
i8042_buf.write_pos++;
i8042_buf.write_pos %= I8042_QUEUE_LEN;
if (unlikely(i8042_buf.write_pos == i8042_buf.read_pos))
printk(KERN_WARNING "i8042.c: ring buffer full\n");
} }
if (!i8042_kbd_values.exists) spin_unlock_irqrestore(&i8042_lock, flags);
goto irq_ret;
serio_interrupt(&i8042_kbd_port, data, dfl, regs); if (unlikely(n_bytes == 0)) {
if (irq) dbg("Interrupt %d, without any data", irq);
return IRQ_NONE;
}
tasklet_schedule(&i8042_tasklet);
irq_ret: return IRQ_HANDLED;
ret = 1;
out:
return IRQ_RETVAL(ret);
} }
/* /*
* i8042_enable_mux_mode checks whether the controller has an active * i8042_enable_mux_mode checks whether the controller has an active
* multiplexor and puts the chip into Multiplexed (as opposed to * multiplexor and puts the chip into Multiplexed (as opposed to
...@@ -474,8 +515,17 @@ static int i8042_enable_mux_mode(struct i8042_values *values, unsigned char *mux ...@@ -474,8 +515,17 @@ static int i8042_enable_mux_mode(struct i8042_values *values, unsigned char *mux
if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xa9) if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xa9)
return -1; return -1;
param = 0xa4; param = 0xa4;
if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b) if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == 0x5b) {
/*
* Do another loop test with the 0x5a value. Doing anything else upsets
* Profusion/ServerWorks OSB4 chipsets.
*/
param = 0x5a;
i8042_command(&param, I8042_CMD_AUX_LOOP);
return -1; return -1;
}
if (mux_version) if (mux_version)
*mux_version = ~param; *mux_version = ~param;
...@@ -530,10 +580,10 @@ static int __init i8042_check_mux(struct i8042_values *values) ...@@ -530,10 +580,10 @@ static int __init i8042_check_mux(struct i8042_values *values)
if (i8042_enable_mux_mode(values, &mux_version)) if (i8042_enable_mux_mode(values, &mux_version))
return -1; return -1;
/* Workaround for broken chips which seem to support MUX, but in reality don't. */ /* Workaround for broken chips which seem to support MUX, but in reality don't. */
/* They all report version 12.10 */ /* They all report version 10.12 */
if (mux_version == 0xCA) if (mux_version == 0xAC)
return -1; return -1;
printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n", printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
...@@ -598,7 +648,7 @@ static int __init i8042_check_aux(struct i8042_values *values) ...@@ -598,7 +648,7 @@ static int __init i8042_check_aux(struct i8042_values *values)
/* /*
* Bit assignment test - filters out PS/2 i8042's in AT mode * Bit assignment test - filters out PS/2 i8042's in AT mode
*/ */
if (i8042_command(&param, I8042_CMD_AUX_DISABLE)) if (i8042_command(&param, I8042_CMD_AUX_DISABLE))
return -1; return -1;
if (i8042_command(&param, I8042_CMD_CTL_RCTR) || (~param & I8042_CTR_AUXDIS)) { if (i8042_command(&param, I8042_CMD_CTL_RCTR) || (~param & I8042_CTR_AUXDIS)) {
...@@ -609,7 +659,7 @@ static int __init i8042_check_aux(struct i8042_values *values) ...@@ -609,7 +659,7 @@ static int __init i8042_check_aux(struct i8042_values *values)
if (i8042_command(&param, I8042_CMD_AUX_ENABLE)) if (i8042_command(&param, I8042_CMD_AUX_ENABLE))
return -1; return -1;
if (i8042_command(&param, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS)) if (i8042_command(&param, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS))
return -1; return -1;
/* /*
* Disable the interface. * Disable the interface.
...@@ -639,7 +689,7 @@ static int __init i8042_port_register(struct i8042_values *values, struct serio ...@@ -639,7 +689,7 @@ static int __init i8042_port_register(struct i8042_values *values, struct serio
if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
printk(KERN_WARNING "i8042.c: Can't write CTR while registering.\n"); printk(KERN_WARNING "i8042.c: Can't write CTR while registering.\n");
values->exists = 0; values->exists = 0;
return -1; return -1;
} }
printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n", printk(KERN_INFO "serio: i8042 %s port at %#lx,%#lx irq %d\n",
...@@ -868,7 +918,7 @@ static int i8042_controller_resume(void) ...@@ -868,7 +918,7 @@ static int i8042_controller_resume(void)
static int i8042_notify_sys(struct notifier_block *this, unsigned long code, static int i8042_notify_sys(struct notifier_block *this, unsigned long code,
void *unused) void *unused)
{ {
if (code==SYS_DOWN || code==SYS_HALT) if (code == SYS_DOWN || code == SYS_HALT)
i8042_controller_cleanup(); i8042_controller_cleanup();
return NOTIFY_DONE; return NOTIFY_DONE;
} }
...@@ -997,20 +1047,21 @@ void __exit i8042_exit(void) ...@@ -997,20 +1047,21 @@ void __exit i8042_exit(void)
sysdev_class_unregister(&kbc_sysclass); sysdev_class_unregister(&kbc_sysclass);
} }
del_timer_sync(&i8042_timer);
i8042_controller_cleanup(); i8042_controller_cleanup();
if (i8042_kbd_values.exists) if (i8042_kbd_values.exists)
serio_unregister_port(&i8042_kbd_port); serio_unregister_port(&i8042_kbd_port);
if (i8042_aux_values.exists) if (i8042_aux_values.exists)
serio_unregister_port(&i8042_aux_port); serio_unregister_port(&i8042_aux_port);
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
if (i8042_mux_values[i].exists) if (i8042_mux_values[i].exists)
serio_unregister_port(i8042_mux_port + i); serio_unregister_port(i8042_mux_port + i);
del_timer_sync(&i8042_timer);
tasklet_kill(&i8042_tasklet);
i8042_platform_exit(); i8042_platform_exit();
} }
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -86,20 +86,9 @@ static int parkbd_write(struct serio *port, unsigned char c) ...@@ -86,20 +86,9 @@ static int parkbd_write(struct serio *port, unsigned char c)
return 0; return 0;
} }
static int parkbd_open(struct serio *port)
{
return 0;
}
static void parkbd_close(struct serio *port)
{
}
static struct serio parkbd_port = static struct serio parkbd_port =
{ {
.write = parkbd_write, .write = parkbd_write,
.open = parkbd_open,
.close = parkbd_close,
.name = parkbd_name, .name = parkbd_name,
.phys = parkbd_phys, .phys = parkbd_phys,
}; };
...@@ -115,7 +104,7 @@ static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -115,7 +104,7 @@ static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
parkbd_writing = 0; parkbd_writing = 0;
parkbd_writelines(3); parkbd_writelines(3);
return; return;
} }
parkbd_writelines(((parkbd_buffer >> parkbd_counter++) & 1) | 2); parkbd_writelines(((parkbd_buffer >> parkbd_counter++) & 1) | 2);
...@@ -131,7 +120,7 @@ static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -131,7 +120,7 @@ static void parkbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if ((parkbd_counter == parkbd_mode + 10) || time_after(jiffies, parkbd_last + HZ/100)) { if ((parkbd_counter == parkbd_mode + 10) || time_after(jiffies, parkbd_last + HZ/100)) {
parkbd_counter = 0; parkbd_counter = 0;
parkbd_buffer = 0; parkbd_buffer = 0;
} }
parkbd_buffer |= (parkbd_readlines() >> 1) << parkbd_counter++; parkbd_buffer |= (parkbd_readlines() >> 1) << parkbd_counter++;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Copyright (c) 2000-2001 Vojtech Pavlik * Copyright (c) 2000-2001 Vojtech Pavlik
* *
* Based on the work of: * Based on the work of:
* Richard Zidlicky <Richard.Zidlicky@stud.informatik.uni-erlangen.de> * Richard Zidlicky <Richard.Zidlicky@stud.informatik.uni-erlangen.de>
*/ */
/* /*
...@@ -47,23 +47,12 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); ...@@ -47,23 +47,12 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver"); MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static int q40kbd_open(struct serio *port)
{
return 0;
}
static void q40kbd_close(struct serio *port)
{
}
static struct serio q40kbd_port = static struct serio q40kbd_port =
{ {
.type = SERIO_8042, .type = SERIO_8042,
.name = "Q40 kbd port", .name = "Q40 kbd port",
.phys = "Q40", .phys = "Q40",
.write = NULL, .write = NULL,
.open = q40kbd_open,
.close = q40kbd_close,
}; };
static irqreturn_t q40kbd_interrupt(int irq, void *dev_id, static irqreturn_t q40kbd_interrupt(int irq, void *dev_id,
......
...@@ -98,7 +98,7 @@ static int rpckbd_open(struct serio *port) ...@@ -98,7 +98,7 @@ static int rpckbd_open(struct serio *port)
static void rpckbd_close(struct serio *port) static void rpckbd_close(struct serio *port)
{ {
free_irq(IRQ_KEYBOARDRX, port); free_irq(IRQ_KEYBOARDRX, port);
free_irq(IRQ_KEYBOARDTX, port); free_irq(IRQ_KEYBOARDTX, port);
} }
static struct serio rpckbd_port = static struct serio rpckbd_port =
......
...@@ -11,18 +11,18 @@ ...@@ -11,18 +11,18 @@
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* Should you need to contact me, the author, you can do so either by * Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
...@@ -108,7 +108,7 @@ void serio_handle_events(void) ...@@ -108,7 +108,7 @@ void serio_handle_events(void)
struct serio_event *event; struct serio_event *event;
list_for_each_safe(node, next, &serio_event_list) { list_for_each_safe(node, next, &serio_event_list) {
event = container_of(node, struct serio_event, node); event = container_of(node, struct serio_event, node);
down(&serio_sem); down(&serio_sem);
if (event->serio == NULL) if (event->serio == NULL)
...@@ -152,7 +152,7 @@ static int serio_thread(void *nothing) ...@@ -152,7 +152,7 @@ static int serio_thread(void *nothing)
do { do {
serio_handle_events(); serio_handle_events();
wait_event_interruptible(serio_wait, !list_empty(&serio_event_list)); wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
if (current->flags & PF_FREEZE) if (current->flags & PF_FREEZE)
refrigerator(PF_FREEZE); refrigerator(PF_FREEZE);
} while (!signal_pending(current)); } while (!signal_pending(current));
...@@ -293,7 +293,7 @@ void serio_unregister_device(struct serio_dev *dev) ...@@ -293,7 +293,7 @@ void serio_unregister_device(struct serio_dev *dev)
int serio_open(struct serio *serio, struct serio_dev *dev) int serio_open(struct serio *serio, struct serio_dev *dev)
{ {
serio->dev = dev; serio->dev = dev;
if (serio->open(serio)) { if (serio->open && serio->open(serio)) {
serio->dev = NULL; serio->dev = NULL;
return -1; return -1;
} }
...@@ -303,7 +303,8 @@ int serio_open(struct serio *serio, struct serio_dev *dev) ...@@ -303,7 +303,8 @@ int serio_open(struct serio *serio, struct serio_dev *dev)
/* called from serio_dev->connect/disconnect methods under serio_sem */ /* called from serio_dev->connect/disconnect methods under serio_sem */
void serio_close(struct serio *serio) void serio_close(struct serio *serio)
{ {
serio->close(serio); if (serio->close)
serio->close(serio);
serio->dev = NULL; serio->dev = NULL;
} }
......
...@@ -48,11 +48,6 @@ static int serport_serio_write(struct serio *serio, unsigned char data) ...@@ -48,11 +48,6 @@ static int serport_serio_write(struct serio *serio, unsigned char data)
return -(serport->tty->driver->write(serport->tty, 0, &data, 1) != 1); return -(serport->tty->driver->write(serport->tty, 0, &data, 1) != 1);
} }
static int serport_serio_open(struct serio *serio)
{
return 0;
}
static void serport_serio_close(struct serio *serio) static void serport_serio_close(struct serio *serio)
{ {
struct serport *serport = serio->driver; struct serport *serport = serio->driver;
...@@ -87,7 +82,6 @@ static int serport_ldisc_open(struct tty_struct *tty) ...@@ -87,7 +82,6 @@ static int serport_ldisc_open(struct tty_struct *tty)
serport->serio.type = SERIO_RS232; serport->serio.type = SERIO_RS232;
serport->serio.write = serport_serio_write; serport->serio.write = serport_serio_write;
serport->serio.open = serport_serio_open;
serport->serio.close = serport_serio_close; serport->serio.close = serport_serio_close;
serport->serio.driver = serport; serport->serio.driver = serport;
...@@ -135,7 +129,7 @@ static int serport_ldisc_room(struct tty_struct *tty) ...@@ -135,7 +129,7 @@ static int serport_ldisc_room(struct tty_struct *tty)
} }
/* /*
* serport_ldisc_read() just waits indefinitely if everything goes well. * serport_ldisc_read() just waits indefinitely if everything goes well.
* However, when the serio driver closes the serio port, it finishes, * However, when the serio driver closes the serio port, it finishes,
* returning 0 characters. * returning 0 characters.
*/ */
...@@ -165,7 +159,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u ...@@ -165,7 +159,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u
static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg) static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg)
{ {
struct serport *serport = (struct serport*) tty->disc_data; struct serport *serport = (struct serport*) tty->disc_data;
if (cmd == SPIOCSTYPE) if (cmd == SPIOCSTYPE)
return get_user(serport->serio.type, (unsigned long __user *) arg); return get_user(serport->serio.type, (unsigned long __user *) arg);
......
...@@ -124,12 +124,10 @@ static void gunze_connect(struct serio *serio, struct serio_dev *dev) ...@@ -124,12 +124,10 @@ static void gunze_connect(struct serio *serio, struct serio_dev *dev)
memset(gunze, 0, sizeof(struct gunze)); memset(gunze, 0, sizeof(struct gunze));
init_input_dev(&gunze->dev); init_input_dev(&gunze->dev);
gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
gunze->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
gunze->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); gunze->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
input_set_abs_params(&gunze->dev, ABS_X, 96, 4000, 0, 0);
gunze->dev.absmin[ABS_X] = 96; gunze->dev.absmin[ABS_Y] = 72; input_set_abs_params(&gunze->dev, ABS_Y, 72, 3000, 0, 0);
gunze->dev.absmax[ABS_X] = 4000; gunze->dev.absmax[ABS_Y] = 3000;
gunze->serio = serio; gunze->serio = serio;
serio->private = gunze; serio->private = gunze;
......
/* /*
* $Id: h3600_ts_input.c,v 1.4 2002/01/23 06:39:37 jsimmons Exp $ * $Id: h3600_ts_input.c,v 1.4 2002/01/23 06:39:37 jsimmons Exp $
* *
* Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com * Copyright (c) 2001 "Crazy" James Simmons jsimmons@transvirtual.com
* *
* Sponsored by Transvirtual Technology. * Sponsored by Transvirtual Technology.
* *
* Derived from the code in h3600_ts.[ch] by Charles Flynn * Derived from the code in h3600_ts.[ch] by Charles Flynn
*/ */
/* /*
...@@ -45,6 +45,10 @@ ...@@ -45,6 +45,10 @@
#include <asm/arch/hardware.h> #include <asm/arch/hardware.h>
#include <asm/arch/irqs.h> #include <asm/arch/irqs.h>
MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
MODULE_DESCRIPTION("H3600 touchscreen driver");
MODULE_LICENSE("GPL");
/* /*
* Definitions & global arrays. * Definitions & global arrays.
*/ */
...@@ -75,7 +79,7 @@ ...@@ -75,7 +79,7 @@
#define MAX_ID 14 #define MAX_ID 14
#define H3600_MAX_LENGTH 16 #define H3600_MAX_LENGTH 16
#define H3600_KEY 0xf #define H3600_KEY 0xf
#define H3600_SCANCODE_RECORD 1 /* 1 -> record button */ #define H3600_SCANCODE_RECORD 1 /* 1 -> record button */
#define H3600_SCANCODE_CALENDAR 2 /* 2 -> calendar */ #define H3600_SCANCODE_CALENDAR 2 /* 2 -> calendar */
...@@ -103,7 +107,7 @@ struct h3600_dev { ...@@ -103,7 +107,7 @@ struct h3600_dev {
char phys[32]; char phys[32];
}; };
static void action_button_handler(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t action_button_handler(int irq, void *dev_id, struct pt_regs *regs)
{ {
int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1; int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1;
struct input_dev *dev = (struct input_dev *) dev_id; struct input_dev *dev = (struct input_dev *) dev_id;
...@@ -111,21 +115,25 @@ static void action_button_handler(int irq, void *dev_id, struct pt_regs *regs) ...@@ -111,21 +115,25 @@ static void action_button_handler(int irq, void *dev_id, struct pt_regs *regs)
input_regs(dev, regs); input_regs(dev, regs);
input_report_key(dev, KEY_ENTER, down); input_report_key(dev, KEY_ENTER, down);
input_sync(dev); input_sync(dev);
return IRQ_HANDLED;
} }
static void npower_button_handler(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t npower_button_handler(int irq, void *dev_id, struct pt_regs *regs)
{ {
int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1; int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1;
struct input_dev *dev = (struct input_dev *) dev_id; struct input_dev *dev = (struct input_dev *) dev_id;
/* /*
* This interrupt is only called when we release the key. So we have * This interrupt is only called when we release the key. So we have
* to fake a key press. * to fake a key press.
*/ */
input_regs(dev, regs); input_regs(dev, regs);
input_report_key(dev, KEY_SUSPEND, 1); input_report_key(dev, KEY_SUSPEND, 1);
input_report_key(dev, KEY_SUSPEND, down); input_report_key(dev, KEY_SUSPEND, down);
input_sync(dev); input_sync(dev);
return IRQ_HANDLED;
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -141,21 +149,21 @@ enum flite_pwr { ...@@ -141,21 +149,21 @@ enum flite_pwr {
* h3600_flite_power: enables or disables power to frontlight, using last bright */ * h3600_flite_power: enables or disables power to frontlight, using last bright */
unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr) unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr)
{ {
unsigned char brightness = ((pwr==FLITE_PWR_OFF) ? 0:flite_brightness); unsigned char brightness = (pwr == FLITE_PWR_OFF) ? 0 : flite_brightness;
struct h3600_dev *ts = dev->private; struct h3600_dev *ts = dev->private;
/* Must be in this order */ /* Must be in this order */
ts->serio->write(ts->serio, 1); ts->serio->write(ts->serio, 1);
ts->serio->write(ts->serio, pwr); ts->serio->write(ts->serio, pwr);
ts->serio->write(ts->serio, brightness); ts->serio->write(ts->serio, brightness);
return 0; return 0;
} }
static int suspended = 0; static int suspended = 0;
static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req, static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
void *data) void *data)
{ {
struct input_dev *dev = (struct input_dev *) data; struct input_dev *dev = (struct input_dev *) data;
switch (req) { switch (req) {
case PM_SUSPEND: /* enter D1-D3 */ case PM_SUSPEND: /* enter D1-D3 */
...@@ -183,7 +191,7 @@ static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req, ...@@ -183,7 +191,7 @@ static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
/* /*
* This function translates the native event packets to linux input event * This function translates the native event packets to linux input event
* packets. Some packets coming from serial are not touchscreen related. In * packets. Some packets coming from serial are not touchscreen related. In
* this case we send them off to be processed elsewhere. * this case we send them off to be processed elsewhere.
*/ */
static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
{ {
...@@ -206,7 +214,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) ...@@ -206,7 +214,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
Note: This is true for non interrupt generated key events. Note: This is true for non interrupt generated key events.
*/ */
case KEYBD_ID: case KEYBD_ID:
down = (ts->buf[0] & 0x80) ? 0 : 1; down = (ts->buf[0] & 0x80) ? 0 : 1;
switch (ts->buf[0] & 0x7f) { switch (ts->buf[0] & 0x7f) {
case H3600_SCANCODE_RECORD: case H3600_SCANCODE_RECORD:
...@@ -218,7 +226,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) ...@@ -218,7 +226,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
case H3600_SCANCODE_CONTACTS: case H3600_SCANCODE_CONTACTS:
key = KEY_PROG2; key = KEY_PROG2;
break; break;
case H3600_SCANCODE_Q: case H3600_SCANCODE_Q:
key = KEY_Q; key = KEY_Q;
break; break;
case H3600_SCANCODE_START: case H3600_SCANCODE_START:
...@@ -237,9 +245,9 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) ...@@ -237,9 +245,9 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
key = KEY_DOWN; key = KEY_DOWN;
break; break;
default: default:
key = 0; key = 0;
} }
if (key) if (key)
input_report_key(dev, key, down); input_report_key(dev, key, down);
break; break;
/* /*
...@@ -251,13 +259,13 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) ...@@ -251,13 +259,13 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
* byte 0 1 2 3 * byte 0 1 2 3
*/ */
case TOUCHS_ID: case TOUCHS_ID:
if (!touched) { if (!touched) {
input_report_key(dev, BTN_TOUCH, 1); input_report_key(dev, BTN_TOUCH, 1);
touched = 1; touched = 1;
} }
if (ts->len) { if (ts->len) {
unsigned short x, y; unsigned short x, y;
x = ts->buf[0]; x <<= 8; x += ts->buf[1]; x = ts->buf[0]; x <<= 8; x += ts->buf[1];
y = ts->buf[2]; y <<= 8; y += ts->buf[3]; y = ts->buf[2]; y <<= 8; y += ts->buf[3];
...@@ -267,7 +275,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) ...@@ -267,7 +275,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
} else { } else {
input_report_key(dev, BTN_TOUCH, 0); input_report_key(dev, BTN_TOUCH, 0);
touched = 0; touched = 0;
} }
break; break;
default: default:
/* Send a non input event elsewhere */ /* Send a non input event elsewhere */
...@@ -280,7 +288,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) ...@@ -280,7 +288,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
/* /*
* h3600ts_event() handles events from the input module. * h3600ts_event() handles events from the input module.
*/ */
static int h3600ts_event(struct input_dev *dev, unsigned int type, static int h3600ts_event(struct input_dev *dev, unsigned int type,
unsigned int code, int value) unsigned int code, int value)
{ {
struct h3600_dev *ts = dev->private; struct h3600_dev *ts = dev->private;
...@@ -290,7 +298,7 @@ static int h3600ts_event(struct input_dev *dev, unsigned int type, ...@@ -290,7 +298,7 @@ static int h3600ts_event(struct input_dev *dev, unsigned int type,
// ts->serio->write(ts->serio, SOME_CMD); // ts->serio->write(ts->serio, SOME_CMD);
return 0; return 0;
} }
} }
return -1; return -1;
} }
...@@ -317,19 +325,19 @@ static int state; ...@@ -317,19 +325,19 @@ static int state;
#define STATE_DATA 2 /* state where we decode data */ #define STATE_DATA 2 /* state where we decode data */
#define STATE_EOF 3 /* state where we decode checksum or EOF */ #define STATE_EOF 3 /* state where we decode checksum or EOF */
static void h3600ts_interrupt(struct serio *serio, unsigned char data, static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data,
unsigned int flags) unsigned int flags, struct pt_regs *regs)
{ {
struct h3600_dev *ts = serio->private; struct h3600_dev *ts = serio->private;
/* /*
* We have a new frame coming in. * We have a new frame coming in.
*/ */
switch (state) { switch (state) {
case STATE_SOF: case STATE_SOF:
if (data == CHAR_SOF) if (data == CHAR_SOF)
state = STATE_ID; state = STATE_ID;
return; break;
case STATE_ID: case STATE_ID:
ts->event = (data & 0xf0) >> 4; ts->event = (data & 0xf0) >> 4;
ts->len = (data & 0xf); ts->len = (data & 0xf);
...@@ -339,23 +347,25 @@ static void h3600ts_interrupt(struct serio *serio, unsigned char data, ...@@ -339,23 +347,25 @@ static void h3600ts_interrupt(struct serio *serio, unsigned char data,
break; break;
} }
ts->chksum = data; ts->chksum = data;
state=(ts->len > 0 ) ? STATE_DATA : STATE_EOF; state = (ts->len > 0) ? STATE_DATA : STATE_EOF;
break; break;
case STATE_DATA: case STATE_DATA:
ts->chksum += data; ts->chksum += data;
ts->buf[ts->idx]= data; ts->buf[ts->idx]= data;
if(++ts->idx == ts->len) if(++ts->idx == ts->len)
state = STATE_EOF; state = STATE_EOF;
break; break;
case STATE_EOF: case STATE_EOF:
state = STATE_SOF; state = STATE_SOF;
if (data == CHAR_EOF || data == ts->chksum ) if (data == CHAR_EOF || data == ts->chksum)
h3600ts_process_packet(ts); h3600ts_process_packet(ts, regs);
break; break;
default: default:
printk("Error3\n"); printk("Error3\n");
break; break;
} }
return IRQ_HANDLED;
} }
/* /*
...@@ -378,11 +388,11 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev) ...@@ -378,11 +388,11 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
init_input_dev(&ts->dev); init_input_dev(&ts->dev);
/* Device specific stuff */ /* Device specific stuff */
set_GPIO_IRQ_edge( GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES ); set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES);
set_GPIO_IRQ_edge( GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE ); set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE);
if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler, if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler,
SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
"h3600_action", &ts->dev)) { "h3600_action", &ts->dev)) {
printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
kfree(ts); kfree(ts);
...@@ -390,24 +400,19 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev) ...@@ -390,24 +400,19 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
} }
if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
"h3600_suspend", &ts->dev)) { "h3600_suspend", &ts->dev)) {
free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev); free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
kfree(ts); kfree(ts);
return; return;
} }
/* Now we have things going we setup our input device */ /* Now we have things going we setup our input device */
ts->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR); ts->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
ts->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); ts->dev.ledbit[0] = BIT(LED_SLEEP);
ts->dev.ledbit[0] = BIT(LED_SLEEP); input_set_abs_params(&ts->dev, ABS_X, 60, 985, 0, 0);
input_set_abs_params(&ts->dev, ABS_Y, 35, 1024, 0, 0);
ts->dev.absmin[ABS_X] = 60; ts->dev.absmin[ABS_Y] = 35;
ts->dev.absmax[ABS_X] = 985; ts->dev.absmax[ABS_Y] = 1024;
ts->dev.absfuzz[ABS_X] = 0; ts->dev.absfuzz[ABS_Y] = 0;
ts->serio = serio;
serio->private = ts;
set_bit(KEY_RECORD, ts->dev.keybit); set_bit(KEY_RECORD, ts->dev.keybit);
set_bit(KEY_Q, ts->dev.keybit); set_bit(KEY_Q, ts->dev.keybit);
...@@ -422,6 +427,9 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev) ...@@ -422,6 +427,9 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
ts->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH); ts->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
ts->dev.keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND); ts->dev.keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND);
ts->serio = serio;
serio->private = ts;
sprintf(ts->phys, "%s/input0", serio->phys); sprintf(ts->phys, "%s/input0", serio->phys);
ts->dev.event = h3600ts_event; ts->dev.event = h3600ts_event;
...@@ -442,7 +450,7 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev) ...@@ -442,7 +450,7 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
//h3600_flite_control(1, 25); /* default brightness */ //h3600_flite_control(1, 25); /* default brightness */
#ifdef CONFIG_PM #ifdef CONFIG_PM
ts->dev.pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT, ts->dev.pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT,
h3600ts_pm_callback); h3600ts_pm_callback);
printk("registered pm callback\n"); printk("registered pm callback\n");
#endif #endif
...@@ -458,7 +466,7 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev) ...@@ -458,7 +466,7 @@ static void h3600ts_connect(struct serio *serio, struct serio_dev *dev)
static void h3600ts_disconnect(struct serio *serio) static void h3600ts_disconnect(struct serio *serio)
{ {
struct h3600_dev *ts = serio->private; struct h3600_dev *ts = serio->private;
free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev); free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev); free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev);
input_unregister_device(&ts->dev); input_unregister_device(&ts->dev);
......
...@@ -655,7 +655,7 @@ struct ff_periodic_effect { ...@@ -655,7 +655,7 @@ struct ff_periodic_effect {
struct ff_envelope envelope; struct ff_envelope envelope;
/* Only used if waveform == FF_CUSTOM */ /* Only used if waveform == FF_CUSTOM */
__u32 custom_len; /* Number of samples */ __u32 custom_len; /* Number of samples */
__s16 *custom_data; /* Buffer of samples */ __s16 *custom_data; /* Buffer of samples */
/* Note: the data pointed by custom_data is copied by the driver. You can /* Note: the data pointed by custom_data is copied by the driver. You can
* therefore dispose of the memory after the upload/update */ * therefore dispose of the memory after the upload/update */
...@@ -749,8 +749,6 @@ struct ff_effect { ...@@ -749,8 +749,6 @@ struct ff_effect {
#define INPUT_KEYCODE(dev, scancode) ((dev->keycodesize == 1) ? ((u8*)dev->keycode)[scancode] : \ #define INPUT_KEYCODE(dev, scancode) ((dev->keycodesize == 1) ? ((u8*)dev->keycode)[scancode] : \
((dev->keycodesize == 2) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode]))) ((dev->keycodesize == 2) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode])))
#define init_input_dev(dev) do { INIT_LIST_HEAD(&((dev)->h_list)); INIT_LIST_HEAD(&((dev)->node)); } while (0)
#define SET_INPUT_KEYCODE(dev, scancode, val) \ #define SET_INPUT_KEYCODE(dev, scancode, val) \
({ unsigned __old; \ ({ unsigned __old; \
switch (dev->keycodesize) { \ switch (dev->keycodesize) { \
...@@ -915,6 +913,12 @@ struct input_handle { ...@@ -915,6 +913,12 @@ struct input_handle {
#define to_handle(n) container_of(n,struct input_handle,d_node) #define to_handle(n) container_of(n,struct input_handle,d_node)
#define to_handle_h(n) container_of(n,struct input_handle,h_node) #define to_handle_h(n) container_of(n,struct input_handle,h_node)
static inline void init_input_dev(struct input_dev *dev)
{
INIT_LIST_HEAD(&dev->h_list);
INIT_LIST_HEAD(&dev->node);
}
void input_register_device(struct input_dev *); void input_register_device(struct input_dev *);
void input_unregister_device(struct input_dev *); void input_unregister_device(struct input_dev *);
...@@ -932,14 +936,51 @@ int input_flush_device(struct input_handle* handle, struct file* file); ...@@ -932,14 +936,51 @@ int input_flush_device(struct input_handle* handle, struct file* file);
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
#define input_report_key(a,b,c) input_event(a, EV_KEY, b, !!(c)) static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)
#define input_report_rel(a,b,c) input_event(a, EV_REL, b, c) {
#define input_report_abs(a,b,c) input_event(a, EV_ABS, b, c) input_event(dev, EV_KEY, code, !!value);
#define input_report_ff(a,b,c) input_event(a, EV_FF, b, c) }
#define input_report_ff_status(a,b,c) input_event(a, EV_FF_STATUS, b, c)
static inline void input_report_rel(struct input_dev *dev, unsigned int code, int value)
#define input_regs(a,b) do { (a)->regs = (b); } while (0) {
#define input_sync(a) do { input_event(a, EV_SYN, SYN_REPORT, 0); (a)->regs = NULL; } while (0) input_event(dev, EV_REL, code, value);
}
static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value)
{
input_event(dev, EV_ABS, code, value);
}
static inline void input_report_ff(struct input_dev *dev, unsigned int code, int value)
{
input_event(dev, EV_FF, code, value);
}
static inline void input_report_ff_status(struct input_dev *dev, unsigned int code, int value)
{
input_event(dev, EV_FF_STATUS, code, value);
}
static inline void input_regs(struct input_dev *dev, struct pt_regs *regs)
{
dev->regs = regs;
}
static inline void input_sync(struct input_dev *dev)
{
input_event(dev, EV_SYN, SYN_REPORT, 0);
dev->regs = NULL;
}
static inline void input_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;
dev->absbit[LONG(axis)] |= BIT(axis);
}
extern struct class_simple *input_class; extern struct class_simple *input_class;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment