summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-09-10 15:54:41 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-10 15:54:41 -0700
commit7f93220b624de1b7d9fcff8a2cebd6fce7ed4665 (patch)
tree5070ec25635008082b47a646d64b4359896c0faa
parent2b8dfec8c8fa4ba5bc946a602e94e99861462cad (diff)
parentd39969deee4b541be4ee5789a2e4c14511c886e2 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
-rw-r--r--Documentation/kernel-parameters.txt1
-rw-r--r--drivers/char/keyboard.c111
-rw-r--r--drivers/input/evdev.c2
-rw-r--r--drivers/input/joystick/iforce/iforce-packets.c32
-rw-r--r--drivers/input/joystick/iforce/iforce-usb.c1
-rw-r--r--drivers/input/keyboard/atkbd.c10
-rw-r--r--drivers/input/keyboard/sunkbd.c2
-rw-r--r--drivers/input/mouse/Makefile2
-rw-r--r--drivers/input/mouse/alps.c2
-rw-r--r--drivers/input/mouse/logips2pp.c13
-rw-r--r--drivers/input/mouse/psmouse-base.c132
-rw-r--r--drivers/input/mouse/psmouse.h52
-rw-r--r--drivers/input/mouse/trackpoint.c304
-rw-r--r--drivers/input/mouse/trackpoint.h147
-rw-r--r--drivers/input/serio/i8042-io.h6
-rw-r--r--drivers/input/serio/i8042-ip22io.h2
-rw-r--r--drivers/input/serio/i8042-jazzio.h2
-rw-r--r--drivers/input/serio/i8042-sparcio.h12
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h72
-rw-r--r--drivers/input/serio/i8042.c199
-rw-r--r--drivers/usb/input/hid-core.c76
-rw-r--r--drivers/usb/input/hid-debug.h34
-rw-r--r--drivers/usb/input/hid-input.c66
-rw-r--r--drivers/usb/input/hid.h9
-rw-r--r--drivers/usb/input/hiddev.c1
-rw-r--r--include/linux/input.h8
26 files changed, 986 insertions, 312 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index d2f0c67ba1fb..db2603ceabba 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -549,6 +549,7 @@ running once the system is up.
keyboard and can not control its state
(Don't attempt to blink the leds)
i8042.noaux [HW] Don't check for auxiliary (== mouse) port
+ i8042.nokbd [HW] Don't check/create keyboard port
i8042.nomux [HW] Don't check presence of an active multiplexing
controller
i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 1745065d8f78..449d029ad4f4 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -14,7 +14,7 @@
* `Sticky' modifier keys, 951006.
*
* 11-11-96: SAK should now work in the raw mode (Martin Mares)
- *
+ *
* Modified to provide 'generic' keyboard support by Hamish Macdonald
* Merge with the m68k keyboard driver and split-off of the PC low-level
* parts by Geert Uytterhoeven, May 1997
@@ -52,7 +52,7 @@ extern void ctrl_alt_del(void);
/*
* Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
* This seems a good reason to start with NumLock off. On HIL keyboards
- * of PARISC machines however there is no NumLock key and everyone expects the keypad
+ * of PARISC machines however there is no NumLock key and everyone expects the keypad
* to be used for numbers.
*/
@@ -76,17 +76,17 @@ void compute_shiftstate(void);
k_meta, k_ascii, k_lock, k_lowercase,\
k_slock, k_dead2, k_ignore, k_ignore
-typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
+typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
char up_flag, struct pt_regs *regs);
static k_handler_fn K_HANDLERS;
static k_handler_fn *k_handler[16] = { K_HANDLERS };
#define FN_HANDLERS\
- fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
- fn_show_state, fn_send_intr, fn_lastcons, fn_caps_toggle,\
- fn_num, fn_hold, fn_scroll_forw, fn_scroll_back,\
- fn_boot_it, fn_caps_on, fn_compose, fn_SAK,\
- fn_dec_console, fn_inc_console, fn_spawn_con, fn_bare_num
+ fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
+ fn_show_state, fn_send_intr, fn_lastcons, fn_caps_toggle,\
+ fn_num, fn_hold, fn_scroll_forw, fn_scroll_back,\
+ fn_boot_it, fn_caps_on, fn_compose, fn_SAK,\
+ fn_dec_console, fn_inc_console, fn_spawn_con, fn_bare_num
typedef void (fn_handler_fn)(struct vc_data *vc, struct pt_regs *regs);
static fn_handler_fn FN_HANDLERS;
@@ -159,13 +159,13 @@ static int sysrq_alt;
*/
int getkeycode(unsigned int scancode)
{
- struct list_head * node;
+ struct list_head *node;
struct input_dev *dev = NULL;
- list_for_each(node,&kbd_handler.h_list) {
- struct input_handle * handle = to_handle_h(node);
- if (handle->dev->keycodesize) {
- dev = handle->dev;
+ list_for_each(node, &kbd_handler.h_list) {
+ struct input_handle *handle = to_handle_h(node);
+ if (handle->dev->keycodesize) {
+ dev = handle->dev;
break;
}
}
@@ -181,15 +181,15 @@ int getkeycode(unsigned int scancode)
int setkeycode(unsigned int scancode, unsigned int keycode)
{
- struct list_head * node;
+ struct list_head *node;
struct input_dev *dev = NULL;
unsigned int i, oldkey;
- list_for_each(node,&kbd_handler.h_list) {
+ list_for_each(node, &kbd_handler.h_list) {
struct input_handle *handle = to_handle_h(node);
- if (handle->dev->keycodesize) {
- dev = handle->dev;
- break;
+ if (handle->dev->keycodesize) {
+ dev = handle->dev;
+ break;
}
}
@@ -200,7 +200,7 @@ int setkeycode(unsigned int scancode, unsigned int keycode)
return -EINVAL;
if (keycode < 0 || keycode > KEY_MAX)
return -EINVAL;
- if (keycode >> (dev->keycodesize * 8))
+ if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
return -EINVAL;
oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode);
@@ -216,11 +216,11 @@ int setkeycode(unsigned int scancode, unsigned int keycode)
}
/*
- * Making beeps and bells.
+ * Making beeps and bells.
*/
static void kd_nosound(unsigned long ignored)
{
- struct list_head * node;
+ struct list_head *node;
list_for_each(node,&kbd_handler.h_list) {
struct input_handle *handle = to_handle_h(node);
@@ -237,12 +237,12 @@ static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
void kd_mksound(unsigned int hz, unsigned int ticks)
{
- struct list_head * node;
+ struct list_head *node;
del_timer(&kd_mksound_timer);
if (hz) {
- list_for_each_prev(node,&kbd_handler.h_list) {
+ list_for_each_prev(node, &kbd_handler.h_list) {
struct input_handle *handle = to_handle_h(node);
if (test_bit(EV_SND, handle->dev->evbit)) {
if (test_bit(SND_TONE, handle->dev->sndbit)) {
@@ -337,19 +337,19 @@ static void to_utf8(struct vc_data *vc, ushort c)
if (c < 0x80)
/* 0******* */
put_queue(vc, c);
- else if (c < 0x800) {
+ else if (c < 0x800) {
/* 110***** 10****** */
- put_queue(vc, 0xc0 | (c >> 6));
+ put_queue(vc, 0xc0 | (c >> 6));
put_queue(vc, 0x80 | (c & 0x3f));
- } else {
+ } else {
/* 1110**** 10****** 10****** */
put_queue(vc, 0xe0 | (c >> 12));
put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
put_queue(vc, 0x80 | (c & 0x3f));
- }
+ }
}
-/*
+/*
* Called after returning from RAW mode or when changing consoles - recompute
* shift_down[] and shift_state from key_down[] maybe called when keymap is
* undefined, so that shiftkey release is seen
@@ -360,7 +360,7 @@ void compute_shiftstate(void)
shift_state = 0;
memset(shift_down, 0, sizeof(shift_down));
-
+
for (i = 0; i < ARRAY_SIZE(key_down); i++) {
if (!key_down[i])
@@ -499,9 +499,9 @@ static void fn_dec_console(struct vc_data *vc, struct pt_regs *regs)
if (want_console != -1)
cur = want_console;
- for (i = cur-1; i != cur; i--) {
+ for (i = cur - 1; i != cur; i--) {
if (i == -1)
- i = MAX_NR_CONSOLES-1;
+ i = MAX_NR_CONSOLES - 1;
if (vc_cons_allocated(i))
break;
}
@@ -567,9 +567,9 @@ static void fn_compose(struct vc_data *vc, struct pt_regs *regs)
static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs)
{
- if (spawnpid)
- if(kill_proc(spawnpid, spawnsig, 1))
- spawnpid = 0;
+ if (spawnpid)
+ if (kill_proc(spawnpid, spawnsig, 1))
+ spawnpid = 0;
}
static void fn_SAK(struct vc_data *vc, struct pt_regs *regs)
@@ -603,8 +603,8 @@ static void k_spec(struct vc_data *vc, unsigned char value, char up_flag, struct
return;
if (value >= ARRAY_SIZE(fn_handler))
return;
- if ((kbd->kbdmode == VC_RAW ||
- kbd->kbdmode == VC_MEDIUMRAW) &&
+ if ((kbd->kbdmode == VC_RAW ||
+ kbd->kbdmode == VC_MEDIUMRAW) &&
value != KVAL(K_SAK))
return; /* SAK is allowed even in raw mode */
fn_handler[value](vc, regs);
@@ -894,11 +894,11 @@ static inline unsigned char getleds(void)
static void kbd_bh(unsigned long dummy)
{
- struct list_head * node;
+ struct list_head *node;
unsigned char leds = getleds();
if (leds != ledstate) {
- list_for_each(node,&kbd_handler.h_list) {
+ list_for_each(node, &kbd_handler.h_list) {
struct input_handle * handle = to_handle_h(node);
input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02));
@@ -963,11 +963,11 @@ static int sparc_l1_a_state = 0;
extern void sun_do_break(void);
#endif
-static int emulate_raw(struct vc_data *vc, unsigned int keycode,
+static int emulate_raw(struct vc_data *vc, unsigned int keycode,
unsigned char up_flag)
{
if (keycode > 255 || !x86_keycodes[keycode])
- return -1;
+ return -1;
switch (keycode) {
case KEY_PAUSE:
@@ -981,7 +981,7 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode,
case KEY_HANJA:
if (!up_flag) put_queue(vc, 0xf2);
return 0;
- }
+ }
if (keycode == KEY_SYSRQ && sysrq_alt) {
put_queue(vc, 0x54 | up_flag);
@@ -1104,11 +1104,12 @@ static void kbd_keycode(unsigned int keycode, int down,
else
clear_bit(keycode, key_down);
- if (rep && (!vc_kbd_mode(kbd, VC_REPEAT) || (tty &&
- (!L_ECHO(tty) && tty->driver->chars_in_buffer(tty))))) {
+ if (rep &&
+ (!vc_kbd_mode(kbd, VC_REPEAT) ||
+ (tty && !L_ECHO(tty) && tty->driver->chars_in_buffer(tty)))) {
/*
* Don't repeat a key if the input buffers are not empty and the
- * characters get aren't echoed locally. This makes key repeat
+ * characters get aren't echoed locally. This makes key repeat
* usable with slow applications and under heavy loads.
*/
return;
@@ -1130,7 +1131,8 @@ static void kbd_keycode(unsigned int keycode, int down,
type = KTYP(keysym);
if (type < 0xf0) {
- if (down && !raw_mode) to_utf8(vc, keysym);
+ if (down && !raw_mode)
+ to_utf8(vc, keysym);
return;
}
@@ -1154,7 +1156,7 @@ static void kbd_keycode(unsigned int keycode, int down,
kbd->slockstate = 0;
}
-static void kbd_event(struct input_handle *handle, unsigned int event_type,
+static void kbd_event(struct input_handle *handle, unsigned int event_type,
unsigned int event_code, int value)
{
if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
@@ -1166,15 +1168,13 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
schedule_console_callback();
}
-static char kbd_name[] = "kbd";
-
/*
* When a keyboard (or other input device) is found, the kbd_connect
* function is called. The function then looks at the device, and if it
* likes it, it can open it and get events from it. In this (kbd_connect)
* function, we should decide which VT to bind that keyboard to initially.
*/
-static struct input_handle *kbd_connect(struct input_handler *handler,
+static struct input_handle *kbd_connect(struct input_handler *handler,
struct input_dev *dev,
struct input_device_id *id)
{
@@ -1182,18 +1182,19 @@ static struct input_handle *kbd_connect(struct input_handler *handler,
int i;
for (i = KEY_RESERVED; i < BTN_MISC; i++)
- if (test_bit(i, dev->keybit)) break;
+ if (test_bit(i, dev->keybit))
+ break;
- if ((i == BTN_MISC) && !test_bit(EV_SND, dev->evbit))
+ if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
return NULL;
- if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
+ if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL)))
return NULL;
memset(handle, 0, sizeof(struct input_handle));
handle->dev = dev;
handle->handler = handler;
- handle->name = kbd_name;
+ handle->name = "kbd";
input_open_device(handle);
kbd_refresh_leds(handle);
@@ -1212,11 +1213,11 @@ static struct input_device_id kbd_ids[] = {
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
.evbit = { BIT(EV_KEY) },
},
-
+
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
.evbit = { BIT(EV_SND) },
- },
+ },
{ }, /* Terminating entry */
};
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 60b696e9336b..3738d173f9a6 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -322,7 +322,7 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL;
if (get_user(v, ip + 1)) return -EFAULT;
if (v < 0 || v > KEY_MAX) return -EINVAL;
- if (v >> (dev->keycodesize * 8)) return -EINVAL;
+ if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8))) return -EINVAL;
u = SET_INPUT_KEYCODE(dev, t, v);
clear_bit(u, dev->keybit);
set_bit(v, dev->keybit);
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 58728ebaaf80..e5a31e55d3e2 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -249,9 +249,6 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data,
int iforce_get_id_packet(struct iforce *iforce, char *packet)
{
- DECLARE_WAITQUEUE(wait, current);
- int timeout = HZ; /* 1 second */
-
switch (iforce->bus) {
case IFORCE_USB:
@@ -260,22 +257,13 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet)
iforce->cr.bRequest = packet[0];
iforce->ctrl->dev = iforce->usbdev;
- set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&iforce->wait, &wait);
-
- if (usb_submit_urb(iforce->ctrl, GFP_ATOMIC)) {
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&iforce->wait, &wait);
+ if (usb_submit_urb(iforce->ctrl, GFP_ATOMIC))
return -1;
- }
- while (timeout && iforce->ctrl->status == -EINPROGRESS)
- timeout = schedule_timeout(timeout);
+ wait_event_interruptible_timeout(iforce->wait,
+ iforce->ctrl->status != -EINPROGRESS, HZ);
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&iforce->wait, &wait);
-
- if (!timeout) {
+ if (iforce->ctrl->status != -EINPROGRESS) {
usb_unlink_urb(iforce->ctrl);
return -1;
}
@@ -290,16 +278,10 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet)
iforce->expect_packet = FF_CMD_QUERY;
iforce_send_packet(iforce, FF_CMD_QUERY, packet);
- set_current_state(TASK_INTERRUPTIBLE);
- add_wait_queue(&iforce->wait, &wait);
-
- while (timeout && iforce->expect_packet)
- timeout = schedule_timeout(timeout);
-
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&iforce->wait, &wait);
+ wait_event_interruptible_timeout(iforce->wait,
+ !iforce->expect_packet, HZ);
- if (!timeout) {
+ if (iforce->expect_packet) {
iforce->expect_packet = 0;
return -1;
}
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 6369a24684fe..58600f91eff5 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -95,6 +95,7 @@ static void iforce_usb_irq(struct urb *urb, struct pt_regs *regs)
goto exit;
}
+ wake_up(&iforce->wait);
iforce_process_packet(iforce,
(iforce->data[0] << 8) | (urb->actual_length - 1), iforce->data + 1, regs);
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 4d4985b59abf..1ad8c2ee7dbf 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -208,6 +208,7 @@ struct atkbd {
unsigned char resend;
unsigned char release;
unsigned char bat_xl;
+ unsigned char err_xl;
unsigned int last;
unsigned long time;
};
@@ -296,15 +297,18 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
if (atkbd->emul ||
!(code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1 ||
code == ATKBD_RET_HANGUEL || code == ATKBD_RET_HANJA ||
- code == ATKBD_RET_ERR ||
+ (code == ATKBD_RET_ERR && !atkbd->err_xl) ||
(code == ATKBD_RET_BAT && !atkbd->bat_xl))) {
atkbd->release = code >> 7;
code &= 0x7f;
}
- if (!atkbd->emul &&
- (code & 0x7f) == (ATKBD_RET_BAT & 0x7f))
+ if (!atkbd->emul) {
+ if ((code & 0x7f) == (ATKBD_RET_BAT & 0x7f))
atkbd->bat_xl = !atkbd->release;
+ if ((code & 0x7f) == (ATKBD_RET_ERR & 0x7f))
+ atkbd->err_xl = !atkbd->release;
+ }
}
switch (code) {
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
index 596964ceb96d..4bae5d89348d 100644
--- a/drivers/input/keyboard/sunkbd.c
+++ b/drivers/input/keyboard/sunkbd.c
@@ -44,7 +44,7 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
static unsigned char sunkbd_keycode[128] = {
- 0,128,114,129,115, 59, 60, 68, 61, 87, 62, 88, 63,100, 64, 0,
+ 0,128,114,129,115, 59, 60, 68, 61, 87, 62, 88, 63,100, 64,112,
65, 66, 67, 56,103,119, 99, 70,105,130,131,108,106, 1, 2, 3,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 41, 14,110,113, 98, 55,
116,132, 83,133,102, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index c4909b49337d..82b330bbf068 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -15,4 +15,4 @@ obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o
obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o
obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o
-psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o lifebook.o
+psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o lifebook.o trackpoint.o
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 0d68e5e0182a..b20783f9748a 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -170,7 +170,7 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
input_report_key(dev, BTN_TOOL_FINGER, z > 0);
if (priv->i->flags & ALPS_WHEEL)
- input_report_rel(dev, REL_WHEEL, ((packet[0] >> 4) & 0x07) | ((packet[2] >> 2) & 0x08));
+ input_report_rel(dev, REL_WHEEL, ((packet[2] << 1) & 0x08) - ((packet[0] >> 4) & 0x07));
if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
input_report_key(dev, BTN_FORWARD, forward);
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 48d2b20d2642..7df96525222e 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -150,12 +150,12 @@ static void ps2pp_set_smartscroll(struct psmouse *psmouse, unsigned int smartscr
ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
}
-static ssize_t psmouse_attr_show_smartscroll(struct psmouse *psmouse, char *buf)
+static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, void *data, char *buf)
{
return sprintf(buf, "%d\n", psmouse->smartscroll ? 1 : 0);
}
-static ssize_t psmouse_attr_set_smartscroll(struct psmouse *psmouse, const char *buf, size_t count)
+static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{
unsigned long value;
char *rest;
@@ -169,7 +169,8 @@ static ssize_t psmouse_attr_set_smartscroll(struct psmouse *psmouse, const char
return count;
}
-PSMOUSE_DEFINE_ATTR(smartscroll);
+PSMOUSE_DEFINE_ATTR(smartscroll, S_IWUSR | S_IRUGO, NULL,
+ ps2pp_attr_show_smartscroll, ps2pp_attr_set_smartscroll);
/*
* Support 800 dpi resolution _only_ if the user wants it (there are good
@@ -194,7 +195,7 @@ static void ps2pp_set_resolution(struct psmouse *psmouse, unsigned int resolutio
static void ps2pp_disconnect(struct psmouse *psmouse)
{
- device_remove_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll);
+ device_remove_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll.dattr);
}
static struct ps2pp_info *get_model_info(unsigned char model)
@@ -222,6 +223,7 @@ static struct ps2pp_info *get_model_info(unsigned char model)
{ 80, PS2PP_KIND_WHEEL, PS2PP_SIDE_BTN | PS2PP_WHEEL },
{ 81, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 83, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
+ { 86, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 88, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
{ 96, 0, 0 },
{ 97, PS2PP_KIND_TP3, PS2PP_WHEEL | PS2PP_HWHEEL },
@@ -379,7 +381,8 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
psmouse->set_resolution = ps2pp_set_resolution;
psmouse->disconnect = ps2pp_disconnect;
- device_create_file(&psmouse->ps2dev.serio->dev, &psmouse_attr_smartscroll);
+ device_create_file(&psmouse->ps2dev.serio->dev,
+ &psmouse_attr_smartscroll.dattr);
}
}
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 12bdd3eff923..af24313ff5bb 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -25,6 +25,7 @@
#include "logips2pp.h"
#include "alps.h"
#include "lifebook.h"
+#include "trackpoint.h"
#define DRIVER_DESC "PS/2 mouse driver"
@@ -57,10 +58,30 @@ static unsigned int psmouse_resetafter;
module_param_named(resetafter, psmouse_resetafter, uint, 0644);
MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
-PSMOUSE_DEFINE_ATTR(protocol);
-PSMOUSE_DEFINE_ATTR(rate);
-PSMOUSE_DEFINE_ATTR(resolution);
-PSMOUSE_DEFINE_ATTR(resetafter);
+PSMOUSE_DEFINE_ATTR(protocol, S_IWUSR | S_IRUGO,
+ NULL,
+ psmouse_attr_show_protocol, psmouse_attr_set_protocol);
+PSMOUSE_DEFINE_ATTR(rate, S_IWUSR | S_IRUGO,
+ (void *) offsetof(struct psmouse, rate),
+ psmouse_show_int_attr, psmouse_attr_set_rate);
+PSMOUSE_DEFINE_ATTR(resolution, S_IWUSR | S_IRUGO,
+ (void *) offsetof(struct psmouse, resolution),
+ psmouse_show_int_attr, psmouse_attr_set_resolution);
+PSMOUSE_DEFINE_ATTR(resetafter, S_IWUSR | S_IRUGO,
+ (void *) offsetof(struct psmouse, resetafter),
+ psmouse_show_int_attr, psmouse_set_int_attr);
+
+static struct attribute *psmouse_attributes[] = {
+ &psmouse_attr_protocol.dattr.attr,
+ &psmouse_attr_rate.dattr.attr,
+ &psmouse_attr_resolution.dattr.attr,
+ &psmouse_attr_resetafter.dattr.attr,
+ NULL
+};
+
+static struct attribute_group psmouse_attribute_group = {
+ .attrs = psmouse_attributes,
+};
__obsolete_setup("psmouse_noext");
__obsolete_setup("psmouse_resolution=");
@@ -520,6 +541,12 @@ static int psmouse_extensions(struct psmouse *psmouse,
return PSMOUSE_IMPS;
/*
+ * Try to initialize the IBM TrackPoint
+ */
+ if (max_proto > PSMOUSE_IMEX && trackpoint_detect(psmouse, set_properties) == 0)
+ return PSMOUSE_TRACKPOINT;
+
+/*
* Okay, all failed, we have a standard mouse here. The number of the buttons
* is still a question, though. We assume 3.
*/
@@ -600,6 +627,12 @@ static struct psmouse_protocol psmouse_protocols[] = {
.init = lifebook_init,
},
{
+ .type = PSMOUSE_TRACKPOINT,
+ .name = "TPPS/2",
+ .alias = "trackpoint",
+ .detect = trackpoint_detect,
+ },
+ {
.type = PSMOUSE_AUTO,
.name = "auto",
.alias = "any",
@@ -787,10 +820,7 @@ static void psmouse_disconnect(struct serio *serio)
psmouse = serio_get_drvdata(serio);
- device_remove_file(&serio->dev, &psmouse_attr_protocol);
- device_remove_file(&serio->dev, &psmouse_attr_rate);
- device_remove_file(&serio->dev, &psmouse_attr_resolution);
- device_remove_file(&serio->dev, &psmouse_attr_resetafter);
+ sysfs_remove_group(&serio->dev.kobj, &psmouse_attribute_group);
down(&psmouse_sem);
@@ -927,10 +957,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
if (parent && parent->pt_activate)
parent->pt_activate(parent);
- device_create_file(&serio->dev, &psmouse_attr_protocol);
- device_create_file(&serio->dev, &psmouse_attr_rate);
- device_create_file(&serio->dev, &psmouse_attr_resolution);
- device_create_file(&serio->dev, &psmouse_attr_resetafter);
+ sysfs_create_group(&serio->dev.kobj, &psmouse_attribute_group);
psmouse_activate(psmouse);
@@ -1027,10 +1054,12 @@ static struct serio_driver psmouse_drv = {
.cleanup = psmouse_cleanup,
};
-ssize_t psmouse_attr_show_helper(struct device *dev, char *buf,
- ssize_t (*handler)(struct psmouse *, char *))
+ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *devattr,
+ char *buf)
{
struct serio *serio = to_serio_port(dev);
+ struct psmouse_attribute *attr = to_psmouse_attr(devattr);
+ struct psmouse *psmouse;
int retval;
retval = serio_pin_driver(serio);
@@ -1042,19 +1071,21 @@ ssize_t psmouse_attr_show_helper(struct device *dev, char *buf,
goto out;
}
- retval = handler(serio_get_drvdata(serio), buf);
+ psmouse = serio_get_drvdata(serio);
+
+ retval = attr->show(psmouse, attr->data, buf);
out:
serio_unpin_driver(serio);
return retval;
}
-ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t count,
- ssize_t (*handler)(struct psmouse *, const char *, size_t))
+ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *devattr,
+ const char *buf, size_t count)
{
struct serio *serio = to_serio_port(dev);
- struct psmouse *psmouse = serio_get_drvdata(serio);
- struct psmouse *parent = NULL;
+ struct psmouse_attribute *attr = to_psmouse_attr(devattr);
+ struct psmouse *psmouse, *parent = NULL;
int retval;
retval = serio_pin_driver(serio);
@@ -1070,6 +1101,8 @@ ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t coun
if (retval)
goto out_unpin;
+ psmouse = serio_get_drvdata(serio);
+
if (psmouse->state == PSMOUSE_IGNORE) {
retval = -ENODEV;
goto out_up;
@@ -1082,7 +1115,7 @@ ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t coun
psmouse_deactivate(psmouse);
- retval = handler(psmouse, buf, count);
+ retval = attr->set(psmouse, attr->data, buf, count);
if (retval != -ENODEV)
psmouse_activate(psmouse);
@@ -1097,12 +1130,34 @@ ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t coun
return retval;
}
-static ssize_t psmouse_attr_show_protocol(struct psmouse *psmouse, char *buf)
+static ssize_t psmouse_show_int_attr(struct psmouse *psmouse, void *offset, char *buf)
+{
+ unsigned long *field = (unsigned long *)((char *)psmouse + (size_t)offset);
+
+ return sprintf(buf, "%lu\n", *field);
+}
+
+static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const char *buf, size_t count)
+{
+ unsigned long *field = (unsigned long *)((char *)psmouse + (size_t)offset);
+ unsigned long value;
+ char *rest;
+
+ value = simple_strtoul(buf, &rest, 10);
+ if (*rest)
+ return -EINVAL;
+
+ *field = value;
+
+ return count;
+}
+
+static ssize_t psmouse_attr_show_protocol(struct psmouse *psmouse, void *data, char *buf)
{
return sprintf(buf, "%s\n", psmouse_protocol_by_type(psmouse->type)->name);
}
-static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, const char *buf, size_t count)
+static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{
struct serio *serio = psmouse->ps2dev.serio;
struct psmouse *parent = NULL;
@@ -1166,12 +1221,7 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, const char *bu
return count;
}
-static ssize_t psmouse_attr_show_rate(struct psmouse *psmouse, char *buf)
-{
- return sprintf(buf, "%d\n", psmouse->rate);
-}
-
-static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, const char *buf, size_t count)
+static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{
unsigned long value;
char *rest;
@@ -1184,12 +1234,7 @@ static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, const char *buf, s
return count;
}
-static ssize_t psmouse_attr_show_resolution(struct psmouse *psmouse, char *buf)
-{
- return sprintf(buf, "%d\n", psmouse->resolution);
-}
-
-static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, const char *buf, size_t count)
+static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{
unsigned long value;
char *rest;
@@ -1202,23 +1247,6 @@ static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, const char *
return count;
}
-static ssize_t psmouse_attr_show_resetafter(struct psmouse *psmouse, char *buf)
-{
- return sprintf(buf, "%d\n", psmouse->resetafter);
-}
-
-static ssize_t psmouse_attr_set_resetafter(struct psmouse *psmouse, const char *buf, size_t count)
-{
- unsigned long value;
- char *rest;
-
- value = simple_strtoul(buf, &rest, 10);
- if (*rest)
- return -EINVAL;
-
- psmouse->resetafter = value;
- return count;
-}
static int psmouse_set_maxproto(const char *val, struct kernel_param *kp)
{
@@ -1234,7 +1262,7 @@ static int psmouse_set_maxproto(const char *val, struct kernel_param *kp)
*((unsigned int *)kp->arg) = proto->type;
- return 0; \
+ return 0;
}
static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp)
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 86691cf43433..45d2bd774f00 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -78,6 +78,7 @@ enum psmouse_type {
PSMOUSE_SYNAPTICS,
PSMOUSE_ALPS,
PSMOUSE_LIFEBOOK,
+ PSMOUSE_TRACKPOINT,
PSMOUSE_AUTO /* This one should always be last */
};