Commit 8724fdb5 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (62 commits)
  Input: atkbd - release previously reserved keycodes 248 - 254
  Input: add KEY_WPS_BUTTON definition
  Input: ads7846 - add regulator support
  Input: winbond-cir - fix suspend/resume
  Input: gamecon - use pr_err() and friends
  Input: gamecon - constify some of the setup structures
  Input: gamecon - simplify pad type handling
  Input: gamecon - simplify coordinate calculation for PSX
  Input: gamecon - fix some formatting issues
  Input: gamecon - add rumble support for N64 pads
  Input: wacom - add device type to device name string
  Input: s3c24xx_ts - report touch only when stylus is down
  Input: s3c24xx_ts - re-enable IRQ on resume
  Input: wacom - constify product features data
  Input: wacom - use per-device instance of wacom_features
  Input: sh_keysc - enable building on SH-Mobile ARM
  Input: wacom - get features from driver info
  Input: rotary-encoder - set gpio direction for each requested gpio
  Input: sh_keysc - update the driver with mode 6
  Input: sh_keysc - switch to using bitmaps
  ...
parents bc535154 35858adb
...@@ -538,3 +538,26 @@ Why: Duplicate functionality with the gspca_zc3xx driver, zc0301 only ...@@ -538,3 +538,26 @@ Why: Duplicate functionality with the gspca_zc3xx driver, zc0301 only
sensors) wich are also supported by the gspca_zc3xx driver sensors) wich are also supported by the gspca_zc3xx driver
(which supports 53 USB-ID's in total) (which supports 53 USB-ID's in total)
Who: Hans de Goede <hdegoede@redhat.com> Who: Hans de Goede <hdegoede@redhat.com>
----------------------------
What: corgikbd, spitzkbd, tosakbd driver
When: 2.6.35
Files: drivers/input/keyboard/{corgi,spitz,tosa}kbd.c
Why: We now have a generic GPIO based matrix keyboard driver that
are fully capable of handling all the keys on these devices.
The original drivers manipulate the GPIO registers directly
and so are difficult to maintain.
Who: Eric Miao <eric.y.miao@gmail.com>
----------------------------
What: corgi_ssp and corgi_ts driver
When: 2.6.35
Files: arch/arm/mach-pxa/corgi_ssp.c, drivers/input/touchscreen/corgi_ts.c
Why: The corgi touchscreen is now deprecated in favour of the generic
ads7846.c driver. The noise reduction technique used in corgi_ts.c,
that's to wait till vsync before ADC sampling, is also integrated into
ads7846 driver now. Provided that the original driver is not generic
and is difficult to maintain, it will be removed later.
Who: Eric Miao <eric.y.miao@gmail.com>
Copyright (C) 2002-2008 Sentelic Corporation. Copyright (C) 2002-2010 Sentelic Corporation.
Last update: Oct-31-2008 Last update: Jan-13-2010
============================================================================== ==============================================================================
* Finger Sensing Pad Intellimouse Mode(scrolling wheel, 4th and 5th buttons) * Finger Sensing Pad Intellimouse Mode(scrolling wheel, 4th and 5th buttons)
...@@ -44,7 +44,7 @@ B) MSID 6: Horizontal and Vertical scrolling. ...@@ -44,7 +44,7 @@ B) MSID 6: Horizontal and Vertical scrolling.
Packet 1 Packet 1
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------| BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
1 |Y|X|y|x|1|M|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 | | |B|F|l|r|u|d| 1 |Y|X|y|x|1|M|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 | | |B|F|r|l|u|d|
|---------------| |---------------| |---------------| |---------------| |---------------| |---------------| |---------------| |---------------|
Byte 1: Bit7 => Y overflow Byte 1: Bit7 => Y overflow
...@@ -59,15 +59,15 @@ Byte 2: X Movement(9-bit 2's complement integers) ...@@ -59,15 +59,15 @@ Byte 2: X Movement(9-bit 2's complement integers)
Byte 3: Y Movement(9-bit 2's complement integers) Byte 3: Y Movement(9-bit 2's complement integers)
Byte 4: Bit0 => the Vertical scrolling movement downward. Byte 4: Bit0 => the Vertical scrolling movement downward.
Bit1 => the Vertical scrolling movement upward. Bit1 => the Vertical scrolling movement upward.
Bit2 => the Vertical scrolling movement rightward. Bit2 => the Horizontal scrolling movement leftward.
Bit3 => the Vertical scrolling movement leftward. Bit3 => the Horizontal scrolling movement rightward.
Bit4 => 1 = 4th mouse button is pressed, Forward one page. Bit4 => 1 = 4th mouse button is pressed, Forward one page.
0 = 4th mouse button is not pressed. 0 = 4th mouse button is not pressed.
Bit5 => 1 = 5th mouse button is pressed, Backward one page. Bit5 => 1 = 5th mouse button is pressed, Backward one page.
0 = 5th mouse button is not pressed. 0 = 5th mouse button is not pressed.
C) MSID 7: C) MSID 7:
# FSP uses 2 packets(8 Bytes) data to represent Absolute Position # FSP uses 2 packets (8 Bytes) to represent Absolute Position.
so we have PACKET NUMBER to identify packets. so we have PACKET NUMBER to identify packets.
If PACKET NUMBER is 0, the packet is Packet 1. If PACKET NUMBER is 0, the packet is Packet 1.
If PACKET NUMBER is 1, the packet is Packet 2. If PACKET NUMBER is 1, the packet is Packet 2.
...@@ -129,7 +129,7 @@ Byte 3: Message Type => 0x00 (Disabled) ...@@ -129,7 +129,7 @@ Byte 3: Message Type => 0x00 (Disabled)
Byte 4: Bit7~Bit0 => Don't Care Byte 4: Bit7~Bit0 => Don't Care
============================================================================== ==============================================================================
* Absolute position for STL3888-A0. * Absolute position for STL3888-Ax.
============================================================================== ==============================================================================
Packet 1 (ABSOLUTE POSITION) Packet 1 (ABSOLUTE POSITION)
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
...@@ -179,14 +179,14 @@ Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0]) ...@@ -179,14 +179,14 @@ Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
Bit5~Bit4 => y2_g Bit5~Bit4 => y2_g
Bit7~Bit6 => x2_g Bit7~Bit6 => x2_g
Notify Packet for STL3888-A0 Notify Packet for STL3888-Ax
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------| BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
1 |1|0|1|P|1|M|R|L| 2 |C|C|C|C|C|C|C|C| 3 |0|0|F|F|0|0|0|i| 4 |r|l|d|u|0|0|0|0| 1 |1|0|1|P|1|M|R|L| 2 |C|C|C|C|C|C|C|C| 3 |0|0|F|F|0|0|0|i| 4 |r|l|d|u|0|0|0|0|
|---------------| |---------------| |---------------| |---------------| |---------------| |---------------| |---------------| |---------------|
Byte 1: Bit7~Bit6 => 00, Normal data packet Byte 1: Bit7~Bit6 => 00, Normal data packet
=> 01, Absolute coordination packet => 01, Absolute coordinates packet
=> 10, Notify packet => 10, Notify packet
Bit5 => 1 Bit5 => 1
Bit4 => when in absolute coordinates mode (valid when EN_PKT_GO is 1): Bit4 => when in absolute coordinates mode (valid when EN_PKT_GO is 1):
...@@ -205,15 +205,106 @@ Byte 4: Bit7 => scroll right button ...@@ -205,15 +205,106 @@ Byte 4: Bit7 => scroll right button
Bit6 => scroll left button Bit6 => scroll left button
Bit5 => scroll down button Bit5 => scroll down button
Bit4 => scroll up button Bit4 => scroll up button
* Note that if gesture and additional button (Bit4~Bit7) * Note that if gesture and additional buttoni (Bit4~Bit7)
happen at the same time, the button information will not happen at the same time, the button information will not
be sent. be sent.
Bit3~Bit0 => Reserved
Sample sequence of Multi-finger, Multi-coordinate mode:
notify packet (valid bit == 1), abs pkt 1, abs pkt 2, abs pkt 1,
abs pkt 2, ..., notify packet (valid bit == 0)
==============================================================================
* Absolute position for STL3888-B0.
==============================================================================
Packet 1(ABSOLUTE POSITION)
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
1 |0|1|V|F|1|0|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |r|l|u|d|X|X|Y|Y|
|---------------| |---------------| |---------------| |---------------|
Byte 1: Bit7~Bit6 => 00, Normal data packet
=> 01, Absolute coordinates packet
=> 10, Notify packet
Bit5 => Valid bit, 0 means that the coordinate is invalid or finger up.
When both fingers are up, the last two reports have zero valid
bit.
Bit4 => finger up/down information. 1: finger down, 0: finger up.
Bit3 => 1
Bit2 => finger index, 0 is the first finger, 1 is the second finger.
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
Byte 2: X coordinate (xpos[9:2])
Byte 3: Y coordinate (ypos[9:2])
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
Bit3~Bit2 => X coordinate (ypos[1:0])
Bit4 => scroll down button
Bit5 => scroll up button
Bit6 => scroll left button
Bit7 => scroll right button
Packet 2 (ABSOLUTE POSITION)
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
1 |0|1|V|F|1|1|R|L| 2 |X|X|X|X|X|X|X|X| 3 |Y|Y|Y|Y|Y|Y|Y|Y| 4 |r|l|u|d|X|X|Y|Y|
|---------------| |---------------| |---------------| |---------------|
Byte 1: Bit7~Bit6 => 00, Normal data packet
=> 01, Absolute coordination packet
=> 10, Notify packet
Bit5 => Valid bit, 0 means that the coordinate is invalid or finger up.
When both fingers are up, the last two reports have zero valid
bit.
Bit4 => finger up/down information. 1: finger down, 0: finger up.
Bit3 => 1
Bit2 => finger index, 0 is the first finger, 1 is the second finger.
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
Byte 2: X coordinate (xpos[9:2])
Byte 3: Y coordinate (ypos[9:2])
Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
Bit3~Bit2 => X coordinate (ypos[1:0])
Bit4 => scroll down button
Bit5 => scroll up button
Bit6 => scroll left button
Bit7 => scroll right button
Notify Packet for STL3888-B0
Bit 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
BYTE |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
1 |1|0|1|P|1|M|R|L| 2 |C|C|C|C|C|C|C|C| 3 |0|0|F|F|0|0|0|i| 4 |r|l|u|d|0|0|0|0|
|---------------| |---------------| |---------------| |---------------|
Byte 1: Bit7~Bit6 => 00, Normal data packet
=> 01, Absolute coordination packet
=> 10, Notify packet
Bit5 => 1
Bit4 => when in absolute coordinate mode (valid when EN_PKT_GO is 1):
0: left button is generated by the on-pad command
1: left button is generated by the external button
Bit3 => 1
Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
Bit1 => Right Button, 1 is pressed, 0 is not pressed.
Bit0 => Left Button, 1 is pressed, 0 is not pressed.
Byte 2: Message Type => 0xB7 (Multi Finger, Multi Coordinate mode)
Byte 3: Bit7~Bit6 => Don't care
Bit5~Bit4 => Number of fingers
Bit3~Bit1 => Reserved
Bit0 => 1: enter gesture mode; 0: leaving gesture mode
Byte 4: Bit7 => scroll right button
Bit6 => scroll left button
Bit5 => scroll up button
Bit4 => scroll down button
* Note that if gesture and additional button(Bit4~Bit7)
happen at the same time, the button information will not
be sent.
Bit3~Bit0 => Reserved Bit3~Bit0 => Reserved
Sample sequence of Multi-finger, Multi-coordinate mode: Sample sequence of Multi-finger, Multi-coordinate mode:
notify packet (valid bit == 1), abs pkt 1, abs pkt 2, abs pkt 1, notify packet (valid bit == 1), abs pkt 1, abs pkt 2, abs pkt 1,
abs pkt 2, ..., notify packet(valid bit == 0) abs pkt 2, ..., notify packet (valid bit == 0)
============================================================================== ==============================================================================
* FSP Enable/Disable packet * FSP Enable/Disable packet
...@@ -409,7 +500,8 @@ offset width default r/w name ...@@ -409,7 +500,8 @@ offset width default r/w name
0: read only, 1: read/write enable 0: read only, 1: read/write enable
(Note that following registers does not require clock gating being (Note that following registers does not require clock gating being
enabled prior to write: 05 06 07 08 09 0c 0f 10 11 12 16 17 18 23 2e enabled prior to write: 05 06 07 08 09 0c 0f 10 11 12 16 17 18 23 2e
40 41 42 43.) 40 41 42 43. In addition to that, this bit must be 1 when gesture
mode is enabled)
0x31 RW on-pad command detection 0x31 RW on-pad command detection
bit7 0 RW on-pad command left button down tag bit7 0 RW on-pad command left button down tag
...@@ -463,6 +555,10 @@ offset width default r/w name ...@@ -463,6 +555,10 @@ offset width default r/w name
absolute coordinates; otherwise, host only receives packets with absolute coordinates; otherwise, host only receives packets with
relative coordinate.) relative coordinate.)
bit7 0 RW EN_PS2_F2: PS/2 gesture mode 2nd
finger packet enable
0: disable, 1: enable
0x43 RW on-pad control 0x43 RW on-pad control
bit0 0 RW on-pad control enable bit0 0 RW on-pad control enable
0: disable, 1: enable 0: disable, 1: enable
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef __ASM_ARCH_EP93XX_KEYPAD_H #ifndef __ASM_ARCH_EP93XX_KEYPAD_H
#define __ASM_ARCH_EP93XX_KEYPAD_H #define __ASM_ARCH_EP93XX_KEYPAD_H
struct matrix_keymap_data;
/* flags for the ep93xx_keypad driver */ /* flags for the ep93xx_keypad driver */
#define EP93XX_KEYPAD_DISABLE_3_KEY (1<<0) /* disable 3-key reset */ #define EP93XX_KEYPAD_DISABLE_3_KEY (1<<0) /* disable 3-key reset */
#define EP93XX_KEYPAD_DIAG_MODE (1<<1) /* diagnostic mode */ #define EP93XX_KEYPAD_DIAG_MODE (1<<1) /* diagnostic mode */
...@@ -15,15 +17,13 @@ ...@@ -15,15 +17,13 @@
/** /**
* struct ep93xx_keypad_platform_data - platform specific device structure * struct ep93xx_keypad_platform_data - platform specific device structure
* @matrix_key_map: array of keycodes defining the keypad matrix * @keymap_data: pointer to &matrix_keymap_data
* @matrix_key_map_size: ARRAY_SIZE(matrix_key_map) * @debounce: debounce start count; terminal count is 0xff
* @debounce: debounce start count; terminal count is 0xff * @prescale: row/column counter pre-scaler load value
* @prescale: row/column counter pre-scaler load value * @flags: see above
* @flags: see above
*/ */
struct ep93xx_keypad_platform_data { struct ep93xx_keypad_platform_data {
unsigned int *matrix_key_map; struct matrix_keymap_data *keymap_data;
int matrix_key_map_size;
unsigned int debounce; unsigned int debounce;
unsigned int prescale; unsigned int prescale;
unsigned int flags; unsigned int flags;
......
...@@ -1185,11 +1185,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) ...@@ -1185,11 +1185,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
rep = (down == 2); rep = (down == 2);
#ifdef CONFIG_MAC_EMUMOUSEBTN
if (mac_hid_mouse_emulate_buttons(1, keycode, down))
return;
#endif /* CONFIG_MAC_EMUMOUSEBTN */
if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw) if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw)
if (emulate_raw(vc, keycode, !down << 7)) if (emulate_raw(vc, keycode, !down << 7))
if (keycode < BTN_MISC && printk_ratelimit()) if (keycode < BTN_MISC && printk_ratelimit())
...@@ -1328,6 +1323,21 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type, ...@@ -1328,6 +1323,21 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
schedule_console_callback(); schedule_console_callback();
} }
static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
{
int i;
if (test_bit(EV_SND, dev->evbit))
return true;
if (test_bit(EV_KEY, dev->evbit))
for (i = KEY_RESERVED; i < BTN_MISC; i++)
if (test_bit(i, dev->keybit))
return true;
return false;
}
/* /*
* When a keyboard (or other input device) is found, the kbd_connect * 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 * function is called. The function then looks at the device, and if it
...@@ -1339,14 +1349,6 @@ static int kbd_connect(struct input_handler *handler, struct input_dev *dev, ...@@ -1339,14 +1349,6 @@ static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
{ {
struct input_handle *handle; struct input_handle *handle;
int error; int error;
int i;
for (i = KEY_RESERVED; i < BTN_MISC; i++)
if (test_bit(i, dev->keybit))
break;
if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
return -ENODEV;
handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
if (!handle) if (!handle)
...@@ -1412,6 +1414,7 @@ MODULE_DEVICE_TABLE(input, kbd_ids); ...@@ -1412,6 +1414,7 @@ MODULE_DEVICE_TABLE(input, kbd_ids);
static struct input_handler kbd_handler = { static struct input_handler kbd_handler = {
.event = kbd_event, .event = kbd_event,
.match = kbd_match,
.connect = kbd_connect, .connect = kbd_connect,
.disconnect = kbd_disconnect, .disconnect = kbd_disconnect,
.start = kbd_start, .start = kbd_start,
......
...@@ -278,6 +278,8 @@ static int evdev_open(struct inode *inode, struct file *file) ...@@ -278,6 +278,8 @@ static int evdev_open(struct inode *inode, struct file *file)
goto err_free_client; goto err_free_client;
file->private_data = client; file->private_data = client;
nonseekable_open(inode, file);
return 0; return 0;
err_free_client: err_free_client:
......
...@@ -46,7 +46,7 @@ struct emu { ...@@ -46,7 +46,7 @@ struct emu {
int size; int size;
}; };
static struct pci_device_id emu_tbl[] = { static const 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 */
......
...@@ -140,7 +140,7 @@ static void __devexit fm801_gp_remove(struct pci_dev *pci) ...@@ -140,7 +140,7 @@ static void __devexit fm801_gp_remove(struct pci_dev *pci)
} }
} }
static struct pci_device_id fm801_gp_id_table[] = { static const struct pci_device_id fm801_gp_id_table[] = {
{ PCI_VENDOR_ID_FORTEMEDIA, PCI_DEVICE_ID_FM801_GP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_FORTEMEDIA, PCI_DEVICE_ID_FM801_GP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0 } { 0 }
}; };
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
* the Free Software Foundation. * the Free Software Foundation.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/ioport.h> #include <linux/ioport.h>
...@@ -190,9 +192,8 @@ static int gameport_bind_driver(struct gameport *gameport, struct gameport_drive ...@@ -190,9 +192,8 @@ static int gameport_bind_driver(struct gameport *gameport, struct gameport_drive
error = device_bind_driver(&gameport->dev); error = device_bind_driver(&gameport->dev);
if (error) { if (error) {
printk(KERN_WARNING dev_warn(&gameport->dev,
"gameport: device_bind_driver() failed " "device_bind_driver() failed for %s (%s) and %s, error: %d\n",
"for %s (%s) and %s, error: %d\n",
gameport->phys, gameport->name, gameport->phys, gameport->name,
drv->description, error); drv->description, error);
drv->disconnect(gameport); drv->disconnect(gameport);
...@@ -209,9 +210,9 @@ static void gameport_find_driver(struct gameport *gameport) ...@@ -209,9 +210,9 @@ static void gameport_find_driver(struct gameport *gameport)
error = device_attach(&gameport->dev); error = device_attach(&gameport->dev);
if (error < 0) if (error < 0)
printk(KERN_WARNING dev_warn(&gameport->dev,
"gameport: device_attach() failed for %s (%s), error: %d\n", "device_attach() failed for %s (%s), error: %d\n",
gameport->phys, gameport->name, error); gameport->phys, gameport->name, error);
} }
...@@ -262,17 +263,14 @@ static int gameport_queue_event(void *object, struct module *owner, ...@@ -262,17 +263,14 @@ static int gameport_queue_event(void *object, struct module *owner,
event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC); event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC);
if (!event) { if (!event) {
printk(KERN_ERR pr_err("Not enough memory to queue event %d\n", event_type);
"gameport: Not enough memory to queue event %d\n",
event_type);
retval = -ENOMEM; retval = -ENOMEM;
goto out; goto out;
} }
if (!try_module_get(owner)) { if (!try_module_get(owner)) {
printk(KERN_WARNING pr_warning("Can't get module reference, dropping event %d\n",
"gameport: Can't get module reference, dropping event %d\n", event_type);
event_type);
kfree(event); kfree(event);
retval = -EINVAL; retval = -EINVAL;
goto out; goto out;
...@@ -298,14 +296,12 @@ static void gameport_free_event(struct gameport_event *event) ...@@ -298,14 +296,12 @@ static void gameport_free_event(struct gameport_event *event)
static void gameport_remove_duplicate_events(struct gameport_event *event) static void gameport_remove_duplicate_events(struct gameport_event *event)
{ {
struct list_head *node, *next; struct gameport_event *e, *next;
struct gameport_event *e;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&gameport_event_lock, flags); spin_lock_irqsave(&gameport_event_lock, flags);
list_for_each_safe(node, next, &gameport_event_list) { list_for_each_entry_safe(e, next, &gameport_event_list, node) {
e = list_entry(node, struct gameport_event, node);
if (event->object == e->object) { if (event->object == e->object) {
/* /*
* If this event is of different type we should not * If this event is of different type we should not
...@@ -315,7 +311,7 @@ static void gameport_remove_duplicate_events(struct gameport_event *event) ...@@ -315,7 +311,7 @@ static void gameport_remove_duplicate_events(struct gameport_event *event)
if (event->type != e->type) if (event->type != e->type)
break; break;
list_del_init(node); list_del_init(&e->node);
gameport_free_event(e); gameport_free_event(e);
} }
} }
...@@ -325,23 +321,18 @@ static void gameport_remove_duplicate_events(struct gameport_event *event) ...@@ -325,23 +321,18 @@ static void gameport_remove_duplicate_events(struct gameport_event *event)
static struct gameport_event *gameport_get_event(void) static struct gameport_event *gameport_get_event(void)
{ {
struct gameport_event *event; struct gameport_event *event = NULL;
struct list_head *node;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&gameport_event_lock, flags); spin_lock_irqsave(&gameport_event_lock, flags);
if (list_empty(&gameport_event_list)) { if (!list_empty(&gameport_event_list)) {
spin_unlock_irqrestore(&gameport_event_lock, flags); event = list_first_entry(&gameport_event_list,
return NULL; struct gameport_event, node);
list_del_init(&event->node);
} }
node = gameport_event_list.next;
event = list_entry(node, struct gameport_event, node);
list_del_init(node);
spin_unlock_irqrestore(&gameport_event_lock, flags); spin_unlock_irqrestore(&gameport_event_lock, flags);
return event; return event;
} }
...@@ -360,16 +351,14 @@ static void gameport_handle_event(void) ...@@ -360,16 +351,14 @@ static void gameport_handle_event(void)
if ((event = gameport_get_event())) { if ((event = gameport_get_event())) {
switch (event->type) { switch (event->type) {
case GAMEPORT_REGISTER_PORT:
gameport_add_port(event->object);
break;
case GAMEPORT_ATTACH_DRIVER: case GAMEPORT_REGISTER_PORT:
gameport_attach_driver(event->object); gameport_add_port(event->object);
break; break;
default: case GAMEPORT_ATTACH_DRIVER:
break; gameport_attach_driver(event->object);
break;
} }
gameport_remove_duplicate_events(event); gameport_remove_duplicate_events(event);
...@@ -385,16 +374,14 @@ static void gameport_handle_event(void) ...@@ -385,16 +374,14 @@ static void gameport_handle_event(void)
*/ */
static void gameport_remove_pending_events(void *object) static void gameport_remove_pending_events(void *object)
{ {
struct list_head *node, *next; struct gameport_event *event, *next;
struct gameport_event *event;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&gameport_event_lock, flags); spin_lock_irqsave(&gameport_event_lock, flags);
list_for_each_safe(node, next, &gameport_event_list) { list_for_each_entry_safe(event, next, &gameport_event_list, node) {
event = list_entry(node, struct gameport_event, node);
if (event->object == object) { if (event->object == object) {
list_del_init(node); list_del_init(&event->node);
gameport_free_event(event); gameport_free_event(event);
} }
} }
...@@ -441,7 +428,6 @@ static int gameport_thread(void *nothing) ...@@ -441,7 +428,6 @@ static int gameport_thread(void *nothing)
kthread_should_stop() || !list_empty(&gameport_event_list)); kthread_should_stop() || !list_empty(&gameport_event_list));
} while (!kthread_should_stop()); } while (!kthread_should_stop());
printk(KERN_DEBUG "gameport: kgameportd exiting\n");
return 0; return 0;
} }
...@@ -453,6 +439,7 @@ static int gameport_thread(void *nothing) ...@@ -453,6 +439,7 @@ static int gameport_thread(void *nothing)
static ssize_t gameport_show_description(struct device *dev, struct device_attribute *attr, char *buf) static ssize_t gameport_show_description(struct device *dev, struct device_attribute *attr, char *buf)
{ {
struct gameport *gameport = to_gameport_port(dev); struct gameport *gameport = to_gameport_port(dev);
return sprintf(buf, "%s\n", gameport->name); return sprintf(buf, "%s\n", gameport->name);
} }
...@@ -521,7 +508,8 @@ static void gameport_init_port(struct gameport *gameport) ...@@ -521,7 +508,8 @@ static void gameport_init_port(struct gameport *gameport)
mutex_init(&gameport->drv_mutex); mutex_init(&gameport->drv_mutex);
device_initialize(&gameport->dev); device_initialize(&gameport->dev);
dev_set_name(&gameport->dev, "gameport%lu", (unsigned long)atomic_inc_return(&gameport_no) - 1); dev_set_name(&gameport->dev, "gameport%lu",
(unsigned long)atomic_inc_return(&gameport_no) - 1);
gameport->dev.bus = &gameport_bus; gameport->dev.bus = &gameport_bus;
gameport->dev.release = gameport_release_port; gameport->dev.release = gameport_release_port;
if (gameport->parent) if (gameport->parent)
...@@ -550,19 +538,17 @@ static void gameport_add_port(struct gameport *gameport) ...@@ -550,19 +538,17 @@ static void gameport_add_port(struct gameport *gameport)
list_add_tail(&gameport->node, &gameport_list); list_add_tail(&gameport->node, &gameport_list);
if (gameport->io) if (gameport->io)
printk(KERN_INFO "gameport: %s is %s, io %#x, speed %dkHz\n", dev_info(&gameport->dev, "%s is %s, io %#x, speed %dkHz\n",
gameport->name, gameport->phys, gameport->io, gameport->speed); gameport->name, gameport->phys, gameport->io, gameport->speed);
else else
printk(KERN_INFO "gameport: %s is %s, speed %dkHz\n", dev_info(&gameport->dev, "%s is %s, speed %dkHz\n",
gameport->name, gameport->phys, gameport->speed); gameport->name, gameport->phys, gameport->speed);
error = device_add(&gameport->dev); error = device_add(&gameport->dev);
if (error) if (error)
printk(KERN_ERR dev_err(&gameport->dev,
"gameport: device_add() failed for %s (%s), error: %d\n", "device_add() failed for %s (%s), error: %d\n",
gameport->phys, gameport->name, error); gameport->phys, gameport->name, error);
else
gameport->registered = 1;
} }
/* /*
...@@ -584,10 +570,8 @@ static void gameport_destroy_port(struct gameport *gameport) ...@@ -584,10 +570,8 @@ static void gameport_destroy_port(struct gameport *gameport)
gameport->parent = NULL; gameport->parent = NULL;
} }
if (gameport->registered) { if (device_is_registered(&gameport->dev))
device_del(&gameport->dev); device_del(&gameport->dev);
gameport->registered = 0;
}
list_del_init(&gameport->node); list_del_init(&gameport->node);
...@@ -705,8 +689,7 @@ static void gameport_attach_driver(struct gameport_driver *drv) ...@@ -705,8 +689,7 @@ static void gameport_attach_driver(struct gameport_driver *drv)
error = driver_attach(&drv->driver); error = driver_attach(&drv->driver);
if (error) if (error)
printk(KERN_ERR pr_err("driver_attach() failed for %s, error: %d\n",
"gameport: driver_attach() failed for %s, error: %d\n",
drv->driver.name, error); drv->driver.name, error);
} }
...@@ -727,8 +710,7 @@ int __gameport_register_driver(struct gameport_driver *drv, struct module *owner ...@@ -727,8 +710,7 @@ int __gameport_register_driver(struct gameport_driver *drv, struct module *owner
error = driver_register(&drv->driver); error = driver_register(&drv->driver);
if (error) { if (error) {
printk(KERN_ERR pr_err("driver_register() failed for %s, error: %d\n",
"gameport: driver_register() failed for %s, error: %d\n",
drv->driver.name, error); drv->driver.name, error);
return error; return error;
} }
...@@ -828,7 +810,7 @@ static int __init gameport_init(void) ...@@ -828,7 +810,7 @@ static int __init gameport_init(void)
error = bus_register(&gameport_bus); error = bus_register(&gameport_bus);
if (error) { if (error) {
printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error); pr_err("failed to register gameport bus, error: %d\n", error);
return error; return error;
} }
...@@ -836,7 +818,7 @@ static int __init gameport_init(void) ...@@ -836,7 +818,7 @@ static int __init gameport_init(void)
if (IS_ERR(gameport_task)) { if (IS_ERR(gameport_task)) {
bus_unregister(&gameport_bus); bus_unregister(&gameport_bus);
error = PTR_ERR(gameport_task); error = PTR_ERR(gameport_task);
printk(KERN_ERR "gameport: Failed to start kgameportd, error: %d\n", error); pr_err("Failed to start kgameportd, error: %d\n", error);
return error; return error;
} }
......
...@@ -166,7 +166,7 @@ static int ns558_isa_probe(int io) ...@@ -166,7 +166,7 @@ static int ns558_isa_probe(int io)
#ifdef CONFIG_PNP #ifdef CONFIG_PNP
static struct pnp_device_id pnp_devids[] = { static const struct pnp_device_id pnp_devids[] = {
{ .id = "@P@0001", .driver_data = 0 }, /* ALS 100 */ { .id = "@P@0001", .driver_data = 0 }, /* ALS 100 */
{ .id = "@P@0020", .driver_data = 0 }, /* ALS 200 */ { .id = "@P@0020", .driver_data = 0 }, /* ALS 200 */
{ .id = "@P@1001", .driver_data = 0 }, /* ALS 100+ */ { .id = "@P@1001", .driver_data = 0 }, /* ALS 100+ */
......
...@@ -87,12 +87,14 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz) ...@@ -87,12 +87,14 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz)
} }
/* /*
* Pass event through all open handles. This function is called with * Pass event first through all filters and then, if event has not been
* filtered out, through all open handles. This function is called with
* dev->event_lock held and interrupts disabled. * dev->event_lock held and interrupts disabled.
*/ */
static void input_pass_event(struct input_dev *dev, static void input_pass_event(struct input_dev *dev,
unsigned int type, unsigned int code, int value) unsigned int type, unsigned int code, int value)
{ {
struct input_handler *handler;
struct input_handle *handle; struct input_handle *handle;
rcu_read_lock(); rcu_read_lock();
...@@ -100,11 +102,25 @@ static void input_pass_event(struct input_dev *dev, ...@@ -100,11 +102,25 @@ static void input_pass_event(struct input_dev *dev,
handle = rcu_dereference(dev->grab); handle = rcu_dereference(dev->grab);
if (handle) if (handle)
handle->handler->event(handle, type, code, value); handle->handler->event(handle, type, code, value);
else else {
list_for_each_entry_rcu(handle, &dev->h_list, d_node) bool filtered = false;
if (handle->open)
handle->handler->event(handle, list_for_each_entry_rcu(handle, &dev->h_list, d_node) {
type, code, value); if (!handle->open)
continue;
handler = handle->handler;
if (!handler->filter) {
if (filtered)
break;
handler->event(handle, type, code, value);
} else if (handler->filter(handle, type, code, value))
filtered = true;
}
}
rcu_read_unlock(); rcu_read_unlock();
} }
...@@ -615,12 +631,12 @@ static int input_default_setkeycode(struct input_dev *dev, ...@@ -615,12 +631,12 @@ static int input_default_setkeycode(struct input_dev *dev,
} }
} }
clear_bit(old_keycode, dev->keybit); __clear_bit(old_keycode, dev->keybit);
set_bit(keycode, dev->keybit); __set_bit(keycode, dev->keybit);
for (i = 0; i < dev->keycodemax; i++) { for (i = 0; i < dev->keycodemax; i++) {
if (input_fetch_keycode(dev, i) == old_keycode) { if (input_fetch_keycode(dev, i) == old_keycode) {
set_bit(old_keycode, dev->keybit); __set_bit(old_keycode, dev->keybit);
break; /* Setting the bit twice is useless, so break */ break; /* Setting the bit twice is useless, so break */
} }
} }
...@@ -678,6 +694,9 @@ int input_set_keycode(struct input_dev *dev, int scancode, int keycode) ...@@ -678,6 +694,9 @@ int input_set_keycode(struct input_dev *dev, int scancode, int keycode)
if (retval) if (retval)
goto out; goto out;
/* Make sure KEY_RESERVED did not get enabled. */
__clear_bit(KEY_RESERVED, dev->keybit);
/* /*
* Simulate keyup event if keycode is not present * Simulate keyup event if keycode is not present
* in the keymap anymore * in the keymap anymore
...@@ -705,12 +724,13 @@ EXPORT_SYMBOL(input_set_keycode); ...@@ -705,12 +724,13 @@ EXPORT_SYMBOL(input_set_keycode);
if (i != BITS_TO_LONGS(max)) \ if (i != BITS_TO_LONGS(max)) \
continue; continue;
static const struct input_device_id *input_match_device(const struct input_device_id *id, static const struct input_device_id *input_match_device(struct input_handler *handler,
struct input_dev *dev) struct input_dev *dev)
{ {
const struct input_device_id *id;
int i; int i;
for (; id->flags || id->driver_info; id++) { for (id = handler->id_table; id->flags || id->driver_info; id++) {
if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
if (id->bustype != dev->id.bustype) if (id->bustype != dev->id.bustype)
...@@ -738,7 +758,8 @@ static const struct input_device_id *input_match_device(const struct input_devic ...@@ -738,7 +758,8 @@ static const struct input_device_id *input_match_device(const struct input_devic
MATCH_BIT(ffbit, FF_MAX); MATCH_BIT(ffbit, FF_MAX);
MATCH_BIT(swbit, SW_MAX); MATCH_BIT(swbit, SW_MAX);
return id; if (!handler->match || handler->match(handler, dev))
return id;
} }
return NULL; return NULL;
...@@ -749,10 +770,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han ...@@ -749,10 +770,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han
const struct input_device_id *id; const struct input_device_id *id;
int error; int error;
if (handler->blacklist && input_match_device(handler->blacklist, dev)) id = input_match_device(handler, dev);
return -ENODEV;
id = input_match_device(handler->id_table, dev);
if (!id) if (!id)
return -ENODEV; return -ENODEV;
...@@ -988,6 +1006,8 @@ static int input_handlers_seq_show(struct seq_file *seq, void *v) ...@@ -988,6 +1006,8 @@ static int input_handlers_seq_show(struct seq_file *seq, void *v)
union input_seq_state *state = (union input_seq_state *)&seq->private; union input_seq_state *state = (union input_seq_state *)&seq->private;
seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name); seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name);
if (handler->filter)
seq_puts(seq, " (filter)");
if (handler->fops) if (handler->fops)
seq_printf(seq, " Minor=%d", handler->minor); seq_printf(seq, " Minor=%d", handler->minor);
seq_putc(seq, '\n'); seq_putc(seq, '\n');
...@@ -1551,6 +1571,25 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int ...@@ -1551,6 +1571,25 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int
} }
EXPORT_SYMBOL(input_set_capability); EXPORT_SYMBOL(input_set_capability);
#define INPUT_CLEANSE_BITMASK(dev, type, bits) \
do { \
if (!test_bit(EV_##type, dev->evbit)) \
memset(dev->bits##bit, 0, \
sizeof(dev->bits##bit)); \
} while (0)
static void input_cleanse_bitmasks(struct input_dev *dev)
{
INPUT_CLEANSE_BITMASK(dev, KEY, key);
INPUT_CLEANSE_BITMASK(dev, REL, rel);
INPUT_CLEANSE_BITMASK(dev, ABS, abs);
INPUT_CLEANSE_BITMASK(dev, MSC, msc);
INPUT_CLEANSE_BITMASK(dev, LED, led);
INPUT_CLEANSE_BITMASK(dev, SND, snd);
INPUT_CLEANSE_BITMASK(dev, FF, ff);
INPUT_CLEANSE_BITMASK(dev, SW, sw);
}
/** /**
* input_register_device - register device with input core * input_register_device - register device with input core
* @dev: device to be registered * @dev: device to be registered
...@@ -1570,13 +1609,19 @@ int input_register_device(struct input_dev *dev) ...@@ -1570,13 +1609,19 @@ int input_register_device(struct input_dev *dev)
const char *path; const char *path;
int error; int error;
/* Every input device generates EV_SYN/SYN_REPORT events. */
__set_bit(EV_SYN, dev->evbit); __set_bit(EV_SYN, dev->evbit);
/* KEY_RESERVED is not supposed to be transmitted to userspace. */
__clear_bit(KEY_RESERVED, dev->keybit);
/* Make sure that bitmasks not mentioned in dev->evbit are clean. */
input_cleanse_bitmasks(dev);
/* /*
* If delay and period are pre-set by the driver, then autorepeating * If delay and period are pre-set by the driver, then autorepeating
* is handled by the driver itself and we don't do it in input.c. * is handled by the driver itself and we don't do it in input.c.
*/ */
init_timer(&dev->timer); init_timer(&dev->timer);
if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) { if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {
dev->timer.data = (long) dev; dev->timer.data = (long) dev;
...@@ -1776,7 +1821,16 @@ int input_register_handle(struct input_handle *handle) ...@@ -1776,7 +1821,16 @@ int input_register_handle(struct input_handle *handle)
error = mutex_lock_interruptible(&dev->mutex); error = mutex_lock_interruptible(&dev->mutex);
if (error) if (error)
return error; return error;
list_add_tail_rcu(&handle->d_node, &dev->h_list);
/*
* Filters go to the head of the list, normal handlers
* to the tail.
*/
if (handler->filter)
list_add_rcu(&handle->d_node, &dev->h_list);
else
list_add_tail_rcu(&handle->d_node, &dev->h_list);
mutex_unlock(&dev->mutex); mutex_unlock(&dev->mutex);
/* /*
......
...@@ -286,6 +286,8 @@ static int joydev_open(struct inode *inode, struct file *file) ...@@ -286,6 +286,8 @@ static int joydev_open(struct inode *inode, struct file *file)
goto err_free_client; goto err_free_client;
file->private_data = client; file->private_data = client;
nonseekable_open(inode, file);
return 0; return 0;
err_free_client: err_free_client:
...@@ -775,6 +777,20 @@ static void joydev_cleanup(struct joydev *joydev) ...@@ -775,6 +777,20 @@ static void joydev_cleanup(struct joydev *joydev)
input_close_device(handle); input_close_device(handle);
} }
static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
{
/* Avoid touchpads and touchscreens */
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
return false;
/* Avoid tablets, digitisers and similar devices */
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
return false;
return true;
}
static int joydev_connect(struct input_handler *handler, struct input_dev *dev, static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
const struct input_device_id *id) const struct input_device_id *id)
{ {
...@@ -894,22 +910,6 @@ static void joydev_disconnect(struct input_handle *handle) ...@@ -894,22 +910,6 @@ static void joydev_disconnect(struct input_handle *handle)
put_device(&joydev->dev); put_device(&joydev->dev);
} }
static const struct input_device_id joydev_blacklist[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT_MASK(EV_KEY) },
.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
}, /* Avoid itouchpads and touchscreens */
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT_MASK(EV_KEY) },
.keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) },
}, /* Avoid tablets, digitisers and similar devices */
{ } /* Terminating entry */
};
static const struct input_device_id joydev_ids[] = { static const struct input_device_id joydev_ids[] = {
{ {
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
...@@ -936,13 +936,13 @@ MODULE_DEVICE_TABLE(input, joydev_ids); ...@@ -936,13 +936,13 @@ MODULE_DEVICE_TABLE(input, joydev_ids);
static struct input_handler joydev_handler = { static struct input_handler joydev_handler = {
.event = joydev_event, .event = joydev_event,
.match = joydev_match,
.connect = joydev_connect, .connect = joydev_connect,
.disconnect = joydev_disconnect, .disconnect = joydev_disconnect,
.fops = &joydev_fops, .fops = &joydev_fops,
.minor = JOYDEV_MINOR_BASE, .minor = JOYDEV_MINOR_BASE,
.name = "joydev", .name = "joydev",
.id_table = joydev_ids, .id_table = joydev_ids,
.blacklist = joydev_blacklist,
}; };
static int __init joydev_init(void) static int __init joydev_init(void)
......
...@@ -221,6 +221,7 @@ config JOYSTICK_DB9 ...@@ -221,6 +221,7 @@ config JOYSTICK_DB9
config JOYSTICK_GAMECON config JOYSTICK_GAMECON
tristate "Multisystem, NES, SNES, N64, PSX joysticks and gamepads" tristate "Multisystem, NES, SNES, N64, PSX joysticks and gamepads"
depends on PARPORT depends on PARPORT
select INPUT_FF_MEMLESS
---help--- ---help---
Say Y here if you have a Nintendo Entertainment System gamepad, Say Y here if you have a Nintendo Entertainment System gamepad,
Super Nintendo Entertainment System gamepad, Nintendo 64 gamepad, Super Nintendo Entertainment System gamepad, Nintendo 64 gamepad,
......
This diff is collapsed.
This diff is collapsed.
...@@ -35,10 +35,10 @@ config KEYBOARD_ADP5520 ...@@ -35,10 +35,10 @@ config KEYBOARD_ADP5520
be called adp5520-keys. be called adp5520-keys.
config KEYBOARD_ADP5588 config KEYBOARD_ADP5588
tristate "ADP5588 I2C QWERTY Keypad and IO Expander" tristate "ADP5588/87 I2C QWERTY Keypad and IO Expander"
depends on I2C depends on I2C
help help
Say Y here if you want to use a ADP5588 attached to your Say Y here if you want to use a ADP5588/87 attached to your
system I2C bus. system I2C bus.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
...@@ -144,13 +144,15 @@ config KEYBOARD_BFIN ...@@ -144,13 +144,15 @@ config KEYBOARD_BFIN
module will be called bf54x-keys. module will be called bf54x-keys.
config KEYBOARD_CORGI config KEYBOARD_CORGI
tristate "Corgi keyboard" tristate "Corgi keyboard (deprecated)"
depends on PXA_SHARPSL depends on PXA_SHARPSL
default y
help help
Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx
series of PDAs. series of PDAs.
This driver is now deprecated, use generic GPIO based matrix
keyboard driver instead.
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 corgikbd. module will be called corgikbd.
...@@ -292,6 +294,15 @@ config KEYBOARD_MAX7359 ...@@ -292,6 +294,15 @@ config KEYBOARD_MAX7359
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 max7359_keypad. module will be called max7359_keypad.
config KEYBOARD_IMX
tristate "IMX keypad support"
depends on ARCH_MXC
help
Enable support for IMX keypad port.
To compile this driver as a module, choose M here: the
module will be called imx_keypad.
config KEYBOARD_NEWTON config KEYBOARD_NEWTON
tristate "Newton keyboard" tristate "Newton keyboard"
select SERIO select SERIO
...@@ -329,13 +340,15 @@ config KEYBOARD_PXA930_ROTARY ...@@ -329,13 +340,15 @@ config KEYBOARD_PXA930_ROTARY
module will be called pxa930_rotary. module will be called pxa930_rotary.
config KEYBOARD_SPITZ config KEYBOARD_SPITZ
tristate "Spitz keyboard" tristate "Spitz keyboard (deprecated)"
depends on PXA_SHARPSL depends on PXA_SHARPSL
default y
help help
Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000, Say Y here to enable the keyboard on the Sharp Zaurus SL-C1000,
SL-C3000 and Sl-C3100 series of PDAs. SL-C3000 and Sl-C3100 series of PDAs.
This driver is now deprecated, use generic GPIO based matrix
keyboard driver instead.
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 spitzkbd. module will be called spitzkbd.
...@@ -363,7 +376,7 @@ config KEYBOARD_SUNKBD ...@@ -363,7 +376,7 @@ config KEYBOARD_SUNKBD
config KEYBOARD_SH_KEYSC config KEYBOARD_SH_KEYSC
tristate "SuperH KEYSC keypad support" tristate "SuperH KEYSC keypad support"
depends on SUPERH depends on SUPERH || ARCH_SHMOBILE
help help
Say Y here if you want to use a keypad attached to the KEYSC block Say Y here if you want to use a keypad attached to the KEYSC block
on SuperH processors such as sh7722 and sh7343. on SuperH processors such as sh7722 and sh7343.
...@@ -402,12 +415,14 @@ config KEYBOARD_TWL4030 ...@@ -402,12 +415,14 @@ config KEYBOARD_TWL4030
module will be called twl4030_keypad. module will be called twl4030_keypad.
config KEYBOARD_TOSA config KEYBOARD_TOSA
tristate "Tosa keyboard" tristate "Tosa keyboard (deprecated)"
depends on MACH_TOSA depends on MACH_TOSA
default y
help help
Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa) Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa)
This driver is now deprecated, use generic GPIO based matrix
keyboard driver instead.
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 tosakbd. module will be called tosakbd.
......
...@@ -17,6 +17,7 @@ obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o ...@@ -17,6 +17,7 @@ obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o
obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o
obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o
obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o
obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o
......
/* /*
* File: drivers/input/keyboard/adp5588_keys.c * File: drivers/input/keyboard/adp5588_keys.c
* Description: keypad driver for ADP5588 I2C QWERTY Keypad and IO Expander * Description: keypad driver for ADP5588 and ADP5587
* I2C QWERTY Keypad and IO Expander
* Bugs: Enter bugs at http://blackfin.uclinux.org/ * Bugs: Enter bugs at http://blackfin.uclinux.org/
* *
* Copyright (C) 2008-2009 Analog Devices Inc. * Copyright (C) 2008-2009 Analog Devices Inc.
...@@ -327,6 +328,7 @@ static const struct dev_pm_ops adp5588_dev_pm_ops = { ...@@ -327,6 +328,7 @@ static const struct dev_pm_ops adp5588_dev_pm_ops = {
static const struct i2c_device_id adp5588_id[] = { static const struct i2c_device_id adp5588_id[] = {
{ KBUILD_MODNAME, 0 }, { KBUILD_MODNAME, 0 },
{ "adp5587-keys", 0 },
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, adp5588_id); MODULE_DEVICE_TABLE(i2c, adp5588_id);
...@@ -357,5 +359,5 @@ module_exit(adp5588_exit); ...@@ -357,5 +359,5 @@ module_exit(adp5588_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
MODULE_DESCRIPTION("ADP5588 Keypad driver"); MODULE_DESCRIPTION("ADP5588/87 Keypad driver");
MODULE_ALIAS("platform:adp5588-keys"); MODULE_ALIAS("platform:adp5588-keys");
This diff is collapsed.
...@@ -69,7 +69,7 @@ struct ep93xx_keypad { ...@@ -69,7 +69,7 @@ struct ep93xx_keypad {
void __iomem *mmio_base; void __iomem *mmio_base;
unsigned int matrix_keycodes[EP93XX_MATRIX_SIZE]; unsigned short keycodes[EP93XX_MATRIX_SIZE];
int key1; int key1;
int key2; int key2;
...@@ -79,24 +79,6 @@ struct ep93xx_keypad { ...@@ -79,24 +79,6 @@ struct ep93xx_keypad {
bool enabled; bool enabled;
}; };
static void ep93xx_keypad_build_keycode(struct ep93xx_keypad *keypad)
{
struct ep93xx_keypad_platform_data *pdata = keypad->pdata;
struct input_dev *input_dev = keypad->input_dev;
unsigned int *key;
int i;
key = &pdata->matrix_key_map[0];
for (i = 0; i < pdata->matrix_key_map_size; i++, key++) {
int row = KEY_ROW(*key);
int col = KEY_COL(*key);
int code = KEY_VAL(*key);
keypad->matrix_keycodes[(row << 3) + col] = code;
__set_bit(code, input_dev->keybit);
}
}
static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id)
{ {
struct ep93xx_keypad *keypad = dev_id; struct ep93xx_keypad *keypad = dev_id;
...@@ -107,10 +89,10 @@ static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) ...@@ -107,10 +89,10 @@ static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id)
status = __raw_readl(keypad->mmio_base + KEY_REG); status = __raw_readl(keypad->mmio_base + KEY_REG);
keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT; keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT;
key1 = keypad->matrix_keycodes[keycode]; key1 = keypad->keycodes[keycode];
keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT; keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT;
key2 = keypad->matrix_keycodes[keycode]; key2 = keypad->keycodes[keycode];
if (status & KEY_REG_2KEYS) { if (status & KEY_REG_2KEYS) {
if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1) if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1)
...@@ -256,6 +238,7 @@ static int ep93xx_keypad_resume(struct platform_device *pdev) ...@@ -256,6 +238,7 @@ static int ep93xx_keypad_resume(struct platform_device *pdev)
static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) static int __devinit ep93xx_keypad_probe(struct platform_device *pdev)
{ {
struct ep93xx_keypad *keypad; struct ep93xx_keypad *keypad;
const struct matrix_keymap_data *keymap_data;
struct input_dev *input_dev; struct input_dev *input_dev;
struct resource *res; struct resource *res;
int err; int err;
...@@ -270,6 +253,12 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) ...@@ -270,6 +253,12 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev)
goto failed_free; goto failed_free;
} }
keymap_data = keypad->pdata->keymap_data;
if (!keymap_data) {
err = -EINVAL;
goto failed_free;
}
keypad->irq = platform_get_irq(pdev, 0); keypad->irq = platform_get_irq(pdev, 0);
if (!keypad->irq) { if (!keypad->irq) {
err = -ENXIO; err = -ENXIO;
...@@ -317,9 +306,9 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) ...@@ -317,9 +306,9 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev)
input_dev->open = ep93xx_keypad_open; input_dev->open = ep93xx_keypad_open;
input_dev->close = ep93xx_keypad_close; input_dev->close = ep93xx_keypad_close;
input_dev->dev.parent = &pdev->dev; input_dev->dev.parent = &pdev->dev;
input_dev->keycode = keypad->matrix_keycodes; input_dev->keycode = keypad->keycodes;
input_dev->keycodesize = sizeof(keypad->matrix_keycodes[0]); input_dev->keycodesize = sizeof(keypad->keycodes[0]);
input_dev->keycodemax = ARRAY_SIZE(keypad->matrix_keycodes); input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes);
input_set_drvdata(input_dev, keypad); input_set_drvdata(input_dev, keypad);
...@@ -327,7 +316,8 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) ...@@ -327,7 +316,8 @@ static int __devinit ep93xx_keypad_probe(struct platform_device *pdev)
if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT)
input_dev->evbit[0] |= BIT_MASK(EV_REP); input_dev->evbit[0] |= BIT_MASK(EV_REP);
ep93xx_keypad_build_keycode(keypad); matrix_keypad_build_keymap(keymap_data, 3,
input_dev->keycode, input_dev->keybit);
platform_set_drvdata(pdev, keypad); platform_set_drvdata(pdev, keypad);
err = request_irq(keypad->irq, ep93xx_keypad_irq_handler, err = request_irq(keypad->irq, ep93xx_keypad_irq_handler,
......
This diff is collapsed.
This diff is collapsed.
...@@ -362,7 +362,7 @@ static int __devexit qt2160_remove(struct i2c_client *client) ...@@ -362,7 +362,7 @@ static int __devexit qt2160_remove(struct i2c_client *client)
return 0; return 0;
} }
static struct i2c_device_id qt2160_idtable[] = { static const struct i2c_device_id qt2160_idtable[] = {
{ "qt2160", 0, }, { "qt2160", 0, },
{ } { }
}; };
......
...@@ -19,101 +19,141 @@ ...@@ -19,101 +19,141 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/input/sh_keysc.h> #include <linux/input/sh_keysc.h>
#include <linux/bitmap.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/io.h> #include <linux/io.h>
#define KYCR1_OFFS 0x00
#define KYCR2_OFFS 0x04
#define KYINDR_OFFS 0x08
#define KYOUTDR_OFFS 0x0c
#define KYCR2_IRQ_LEVEL 0x10
#define KYCR2_IRQ_DISABLED 0x00
static const struct { static const struct {
unsigned char kymd, keyout, keyin; unsigned char kymd, keyout, keyin;
} sh_keysc_mode[] = { } sh_keysc_mode[] = {
[SH_KEYSC_MODE_1] = { 0, 6, 5 }, [SH_KEYSC_MODE_1] = { 0, 6, 5 },
[SH_KEYSC_MODE_2] = { 1, 5, 6 }, [SH_KEYSC_MODE_2] = { 1, 5, 6 },
[SH_KEYSC_MODE_3] = { 2, 4, 7 }, [SH_KEYSC_MODE_3] = { 2, 4, 7 },
[SH_KEYSC_MODE_4] = { 3, 6, 6 },
[SH_KEYSC_MODE_5] = { 4, 6, 7 },
[SH_KEYSC_MODE_6] = { 5, 7, 7 },
}; };
struct sh_keysc_priv { struct sh_keysc_priv {
void __iomem *iomem_base; void __iomem *iomem_base;
struct clk *clk; struct clk *clk;
unsigned long last_keys; DECLARE_BITMAP(last_keys, SH_KEYSC_MAXKEYS);
struct input_dev *input; struct input_dev *input;
struct sh_keysc_info pdata; struct sh_keysc_info pdata;
}; };
#define KYCR1 0
#define KYCR2 1
#define KYINDR 2
#define KYOUTDR 3
#define KYCR2_IRQ_LEVEL 0x10
#define KYCR2_IRQ_DISABLED 0x00
static unsigned long sh_keysc_read(struct sh_keysc_priv *p, int reg_nr)
{
return ioread16(p->iomem_base + (reg_nr << 2));
}
static void sh_keysc_write(struct sh_keysc_priv *p, int reg_nr,
unsigned long value)
{
iowrite16(value, p->iomem_base + (reg_nr << 2));
}
static void sh_keysc_level_mode(struct sh_keysc_priv *p,
unsigned long keys_set)
{
struct sh_keysc_info *pdata = &p->pdata;
sh_keysc_write(p, KYOUTDR, 0);
sh_keysc_write(p, KYCR2, KYCR2_IRQ_LEVEL | (keys_set << 8));
if (pdata->kycr2_delay)
udelay(pdata->kycr2_delay);
}
static void sh_keysc_map_dbg(struct device *dev, unsigned long *map,
const char *str)
{
int k;
for (k = 0; k < BITS_TO_LONGS(SH_KEYSC_MAXKEYS); k++)
dev_dbg(dev, "%s[%d] 0x%lx\n", str, k, map[k]);
}
static irqreturn_t sh_keysc_isr(int irq, void *dev_id) static irqreturn_t sh_keysc_isr(int irq, void *dev_id)
{ {
struct platform_device *pdev = dev_id; struct platform_device *pdev = dev_id;
struct sh_keysc_priv *priv = platform_get_drvdata(pdev); struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
struct sh_keysc_info *pdata = &priv->pdata; struct sh_keysc_info *pdata = &priv->pdata;
unsigned long keys, keys1, keys0, mask; int keyout_nr = sh_keysc_mode[pdata->mode].keyout;
int keyin_nr = sh_keysc_mode[pdata->mode].keyin;
DECLARE_BITMAP(keys, SH_KEYSC_MAXKEYS);
DECLARE_BITMAP(keys0, SH_KEYSC_MAXKEYS);
DECLARE_BITMAP(keys1, SH_KEYSC_MAXKEYS);
unsigned char keyin_set, tmp; unsigned char keyin_set, tmp;
int i, k; int i, k, n;
dev_dbg(&pdev->dev, "isr!\n"); dev_dbg(&pdev->dev, "isr!\n");
keys1 = ~0; bitmap_fill(keys1, SH_KEYSC_MAXKEYS);
keys0 = 0; bitmap_zero(keys0, SH_KEYSC_MAXKEYS);
do { do {
keys = 0; bitmap_zero(keys, SH_KEYSC_MAXKEYS);
keyin_set = 0; keyin_set = 0;
iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED);
for (i = 0; i < keyout_nr; i++) {
n = keyin_nr * i;
for (i = 0; i < sh_keysc_mode[pdata->mode].keyout; i++) { /* drive one KEYOUT pin low, read KEYIN pins */
iowrite16(0xfff ^ (3 << (i * 2)), sh_keysc_write(priv, KYOUTDR, 0xffff ^ (3 << (i * 2)));
priv->iomem_base + KYOUTDR_OFFS);
udelay(pdata->delay); udelay(pdata->delay);
tmp = ioread16(priv->iomem_base + KYINDR_OFFS); tmp = sh_keysc_read(priv, KYINDR);
keys |= tmp << (sh_keysc_mode[pdata->mode].keyin * i);
tmp ^= (1 << sh_keysc_mode[pdata->mode].keyin) - 1;
keyin_set |= tmp;
}
iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); /* set bit if key press has been detected */
iowrite16(KYCR2_IRQ_LEVEL | (keyin_set << 8), for (k = 0; k < keyin_nr; k++) {
priv->iomem_base + KYCR2_OFFS); if (tmp & (1 << k))
__set_bit(n + k, keys);
}
if (pdata->kycr2_delay) /* keep track of which KEYIN bits that have been set */
udelay(pdata->kycr2_delay); keyin_set |= tmp ^ ((1 << keyin_nr) - 1);
}
keys ^= ~0; sh_keysc_level_mode(priv, keyin_set);
keys &= (1 << (sh_keysc_mode[pdata->mode].keyin *
sh_keysc_mode[pdata->mode].keyout)) - 1;
keys1 &= keys;
keys0 |= keys;
dev_dbg(&pdev->dev, "keys 0x%08lx\n", keys); bitmap_complement(keys, keys, SH_KEYSC_MAXKEYS);
bitmap_and(keys1, keys1, keys, SH_KEYSC_MAXKEYS);
bitmap_or(keys0, keys0, keys, SH_KEYSC_MAXKEYS);
} while (ioread16(priv->iomem_base + KYCR2_OFFS) & 0x01); sh_keysc_map_dbg(&pdev->dev, keys, "keys");
dev_dbg(&pdev->dev, "last_keys 0x%08lx keys0 0x%08lx keys1 0x%08lx\n", } while (sh_keysc_read(priv, KYCR2) & 0x01);
priv->last_keys, keys0, keys1);
sh_keysc_map_dbg(&pdev->dev, priv->last_keys, "last_keys");
sh_keysc_map_dbg(&pdev->dev, keys0, "keys0");
sh_keysc_map_dbg(&pdev->dev, keys1, "keys1");
for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { for (i = 0; i < SH_KEYSC_MAXKEYS; i++) {
k = pdata->keycodes[i]; k = pdata->keycodes[i];
if (!k) if (!k)
continue; continue;
mask = 1 << i; if (test_bit(i, keys0) == test_bit(i, priv->last_keys))
if (!((priv->last_keys ^ keys0) & mask))
continue; continue;
if ((keys1 | keys0) & mask) { if (test_bit(i, keys1) || test_bit(i, keys0)) {
input_event(priv->input, EV_KEY, k, 1); input_event(priv->input, EV_KEY, k, 1);
priv->last_keys |= mask; __set_bit(i, priv->last_keys);
} }
if (!(keys1 & mask)) { if (!test_bit(i, keys1)) {
input_event(priv->input, EV_KEY, k, 0); input_event(priv->input, EV_KEY, k, 0);
priv->last_keys &= ~mask; __clear_bit(i, priv->last_keys);
} }
} }
...@@ -122,8 +162,6 @@ static irqreturn_t sh_keysc_isr(int irq, void *dev_id) ...@@ -122,8 +162,6 @@ static irqreturn_t sh_keysc_isr(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
#define res_size(res) ((res)->end - (res)->start + 1)
static int __devinit sh_keysc_probe(struct platform_device *pdev) static int __devinit sh_keysc_probe(struct platform_device *pdev)
{ {
struct sh_keysc_priv *priv; struct sh_keysc_priv *priv;
...@@ -164,7 +202,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) ...@@ -164,7 +202,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata)); memcpy(&priv->pdata, pdev->dev.platform_data, sizeof(priv->pdata));
pdata = &priv->pdata; pdata = &priv->pdata;
priv->iomem_base = ioremap_nocache(res->start, res_size(res)); priv->iomem_base = ioremap_nocache(res->start, resource_size(res));
if (priv->iomem_base == NULL) { if (priv->iomem_base == NULL) {
dev_err(&pdev->dev, "failed to remap I/O memory\n"); dev_err(&pdev->dev, "failed to remap I/O memory\n");
error = -ENXIO; error = -ENXIO;
...@@ -220,10 +258,9 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) ...@@ -220,10 +258,9 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
clk_enable(priv->clk); clk_enable(priv->clk);
iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) | sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) |
pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); pdata->scan_timing);
iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); sh_keysc_level_mode(priv, 0);
iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS);
device_init_wakeup(&pdev->dev, 1); device_init_wakeup(&pdev->dev, 1);
...@@ -248,7 +285,7 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) ...@@ -248,7 +285,7 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev)
{ {
struct sh_keysc_priv *priv = platform_get_drvdata(pdev); struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
iowrite16(KYCR2_IRQ_DISABLED, priv->iomem_base + KYCR2_OFFS); sh_keysc_write(priv, KYCR2, KYCR2_IRQ_DISABLED);
input_unregister_device(priv->input); input_unregister_device(priv->input);
free_irq(platform_get_irq(pdev, 0), pdev); free_irq(platform_get_irq(pdev, 0), pdev);
...@@ -270,7 +307,7 @@ static int sh_keysc_suspend(struct device *dev) ...@@ -270,7 +307,7 @@ static int sh_keysc_suspend(struct device *dev)
int irq = platform_get_irq(pdev, 0); int irq = platform_get_irq(pdev, 0);
unsigned short value; unsigned short value;
value = ioread16(priv->iomem_base + KYCR1_OFFS); value = sh_keysc_read(priv, KYCR1);
if (device_may_wakeup(dev)) { if (device_may_wakeup(dev)) {
value |= 0x80; value |= 0x80;
...@@ -279,7 +316,7 @@ static int sh_keysc_suspend(struct device *dev) ...@@ -279,7 +316,7 @@ static int sh_keysc_suspend(struct device *dev)
value &= ~0x80; value &= ~0x80;
} }
iowrite16(value, priv->iomem_base + KYCR1_OFFS); sh_keysc_write(priv, KYCR1, value);
return 0; return 0;
} }
......
...@@ -149,7 +149,7 @@ static void apanel_shutdown(struct i2c_client *client) ...@@ -149,7 +149,7 @@ static void apanel_shutdown(struct i2c_client *client)
apanel_remove(client); apanel_remove(client);
} }
static struct i2c_device_id apanel_id[] = { static const struct i2c_device_id apanel_id[] = {
{ "fujitsu_apanel", 0 }, { "fujitsu_apanel", 0 },
{ } { }
}; };
......
...@@ -152,6 +152,13 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) ...@@ -152,6 +152,13 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
goto exit_unregister_input; goto exit_unregister_input;
} }
err = gpio_direction_input(pdata->gpio_a);
if (err) {
dev_err(&pdev->dev, "unable to set GPIO %d for input\n",
pdata->gpio_a);
goto exit_unregister_input;
}
err = gpio_request(pdata->gpio_b, DRV_NAME); err = gpio_request(pdata->gpio_b, DRV_NAME);
if (err) { if (err) {
dev_err(&pdev->dev, "unable to request GPIO %d\n", dev_err(&pdev->dev, "unable to request GPIO %d\n",
...@@ -159,6 +166,13 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) ...@@ -159,6 +166,13 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
goto exit_free_gpio_a; goto exit_free_gpio_a;
} }
err = gpio_direction_input(pdata->gpio_b);
if (err) {
dev_err(&pdev->dev, "unable to set GPIO %d for input\n",
pdata->gpio_b);
goto exit_free_gpio_a;
}
/* request the IRQs */ /* request the IRQs */
err = request_irq(encoder->irq_a, &rotary_encoder_irq, err = request_irq(encoder->irq_a, &rotary_encoder_irq,
IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/uinput.h> #include <linux/uinput.h>
...@@ -284,7 +283,6 @@ static int uinput_open(struct inode *inode, struct file *file) ...@@ -284,7 +283,6 @@ static int uinput_open(struct inode *inode, struct file *file)
if (!newdev) if (!newdev)
return -ENOMEM; return -ENOMEM;
lock_kernel();
mutex_init(&newdev->mutex); mutex_init(&newdev->mutex);
spin_lock_init(&newdev->requests_lock); spin_lock_init(&newdev->requests_lock);
init_waitqueue_head(&newdev->requests_waitq); init_waitqueue_head(&newdev->requests_waitq);
...@@ -292,7 +290,7 @@ static int uinput_open(struct inode *inode, struct file *file) ...@@ -292,7 +290,7 @@ static int uinput_open(struct inode *inode, struct file *file)
newdev->state = UIST_NEW_DEVICE; newdev->state = UIST_NEW_DEVICE;
file->private_data = newdev; file->private_data = newdev;
unlock_kernel(); nonseekable_open(inode, file);
return 0; return 0;
} }
......
...@@ -538,6 +538,7 @@ wbcir_reset_irdata(struct wbcir_data *data) ...@@ -538,6 +538,7 @@ wbcir_reset_irdata(struct wbcir_data *data)
data->irdata_count = 0; data->irdata_count = 0;
data->irdata_off = 0; data->irdata_off = 0;
data->irdata_error = 0; data->irdata_error = 0;
data->idle_count = 0;
} }
/* Adds one bit of irdata */ /* Adds one bit of irdata */
...@@ -1006,7 +1007,6 @@ wbcir_irq_handler(int irqno, void *cookie) ...@@ -1006,7 +1007,6 @@ wbcir_irq_handler(int irqno, void *cookie)
} }
wbcir_reset_irdata(data); wbcir_reset_irdata(data);
data->idle_count = 0;
} }
out: out:
...@@ -1018,7 +1018,7 @@ wbcir_irq_handler(int irqno, void *cookie) ...@@ -1018,7 +1018,7 @@ wbcir_irq_handler(int irqno, void *cookie)
/***************************************************************************** /*****************************************************************************
* *
* SUSPEND/RESUME FUNCTIONS * SETUP/INIT/SUSPEND/RESUME FUNCTIONS
* *
*****************************************************************************/ *****************************************************************************/
...@@ -1197,7 +1197,16 @@ wbcir_shutdown(struct pnp_dev *device) ...@@ -1197,7 +1197,16 @@ wbcir_shutdown(struct pnp_dev *device)
} }
/* Disable interrupts */ /* Disable interrupts */
wbcir_select_bank(data, WBCIR_BANK_0);
outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER); outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
/*
* ACPI will set the HW disable bit for SP3 which means that the
* output signals are left in an undefined state which may cause
* spurious interrupts which we need to ignore until the hardware
* is reinitialized.
*/
disable_irq(data->irq);
} }
static int static int
...@@ -1207,37 +1216,15 @@ wbcir_suspend(struct pnp_dev *device, pm_message_t state) ...@@ -1207,37 +1216,15 @@ wbcir_suspend(struct pnp_dev *device, pm_message_t state)
return 0; return 0;
} }
static int
wbcir_resume(struct pnp_dev *device)
{
struct wbcir_data *data = pnp_get_drvdata(device);
/* Clear BUFF_EN, Clear END_EN, Clear MATCH_EN */
wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_EV_EN, 0x00, 0x07);
/* Clear CEIR_EN */
wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01);
/* Enable interrupts */
wbcir_reset_irdata(data);
outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
return 0;
}
/*****************************************************************************
*
* SETUP/INIT FUNCTIONS
*
*****************************************************************************/
static void static void
wbcir_cfg_ceir(struct wbcir_data *data) wbcir_init_hw(struct wbcir_data *data)
{ {
u8 tmp; u8 tmp;
/* Disable interrupts */
wbcir_select_bank(data, WBCIR_BANK_0);
outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
/* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */ /* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */
tmp = protocol << 4; tmp = protocol << 4;
if (invert) if (invert)
...@@ -1264,6 +1251,93 @@ wbcir_cfg_ceir(struct wbcir_data *data) ...@@ -1264,6 +1251,93 @@ wbcir_cfg_ceir(struct wbcir_data *data)
* set SP3_IRRX_SW to binary 01, helpfully not documented * set SP3_IRRX_SW to binary 01, helpfully not documented
*/ */
outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS); outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS);
/* Enable extended mode */
wbcir_select_bank(data, WBCIR_BANK_2);
outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1);
/*
* Configure baud generator, IR data will be sampled at
* a bitrate of: (24Mhz * prescaler) / (divisor * 16).
*
* The ECIR registers include a flag to change the
* 24Mhz clock freq to 48Mhz.
*
* It's not documented in the specs, but fifo levels
* other than 16 seems to be unsupported.
*/
/* prescaler 1.0, tx/rx fifo lvl 16 */
outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2);
/* Set baud divisor to generate one byte per bit/cell */
switch (protocol) {
case IR_PROTOCOL_RC5:
outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL);
break;
case IR_PROTOCOL_RC6:
outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL);
break;
case IR_PROTOCOL_NEC:
outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL);
break;
}
outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH);
/* Set CEIR mode */
wbcir_select_bank(data, WBCIR_BANK_0);
outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR);
inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */
inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */
/* Disable RX demod, run-length encoding/decoding, set freq span */
wbcir_select_bank(data, WBCIR_BANK_7);
outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG);
/* Disable timer */
wbcir_select_bank(data, WBCIR_BANK_4);
outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1);
/* Enable MSR interrupt, Clear AUX_IRX */
wbcir_select_bank(data, WBCIR_BANK_5);
outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2);
/* Disable CRC */
wbcir_select_bank(data, WBCIR_BANK_6);
outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3);
/* Set RX/TX (de)modulation freq, not really used */
wbcir_select_bank(data, WBCIR_BANK_7);
outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC);
outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC);
/* Set invert and pin direction */
if (invert)
outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4);
else
outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4);
/* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */
wbcir_select_bank(data, WBCIR_BANK_0);
outb(0x97, data->sbase + WBCIR_REG_SP3_FCR);
/* Clear AUX status bits */
outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
/* Enable interrupts */
wbcir_reset_irdata(data);
outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
}
static int
wbcir_resume(struct pnp_dev *device)
{
struct wbcir_data *data = pnp_get_drvdata(device);
wbcir_init_hw(data);
enable_irq(data->irq);
return 0;
} }
static int __devinit static int __devinit
...@@ -1393,86 +1467,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) ...@@ -1393,86 +1467,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
device_init_wakeup(&device->dev, 1); device_init_wakeup(&device->dev, 1);
wbcir_cfg_ceir(data); wbcir_init_hw(data);
/* Disable interrupts */
wbcir_select_bank(data, WBCIR_BANK_0);
outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
/* Enable extended mode */
wbcir_select_bank(data, WBCIR_BANK_2);
outb(WBCIR_EXT_ENABLE, data->sbase + WBCIR_REG_SP3_EXCR1);
/*
* Configure baud generator, IR data will be sampled at
* a bitrate of: (24Mhz * prescaler) / (divisor * 16).
*
* The ECIR registers include a flag to change the
* 24Mhz clock freq to 48Mhz.
*
* It's not documented in the specs, but fifo levels
* other than 16 seems to be unsupported.
*/
/* prescaler 1.0, tx/rx fifo lvl 16 */
outb(0x30, data->sbase + WBCIR_REG_SP3_EXCR2);
/* Set baud divisor to generate one byte per bit/cell */
switch (protocol) {
case IR_PROTOCOL_RC5:
outb(0xA7, data->sbase + WBCIR_REG_SP3_BGDL);
break;
case IR_PROTOCOL_RC6:
outb(0x53, data->sbase + WBCIR_REG_SP3_BGDL);
break;
case IR_PROTOCOL_NEC:
outb(0x69, data->sbase + WBCIR_REG_SP3_BGDL);
break;
}
outb(0x00, data->sbase + WBCIR_REG_SP3_BGDH);
/* Set CEIR mode */
wbcir_select_bank(data, WBCIR_BANK_0);
outb(0xC0, data->sbase + WBCIR_REG_SP3_MCR);
inb(data->sbase + WBCIR_REG_SP3_LSR); /* Clear LSR */
inb(data->sbase + WBCIR_REG_SP3_MSR); /* Clear MSR */
/* Disable RX demod, run-length encoding/decoding, set freq span */
wbcir_select_bank(data, WBCIR_BANK_7);
outb(0x10, data->sbase + WBCIR_REG_SP3_RCCFG);
/* Disable timer */
wbcir_select_bank(data, WBCIR_BANK_4);
outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1);
/* Enable MSR interrupt, Clear AUX_IRX */
wbcir_select_bank(data, WBCIR_BANK_5);
outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2);
/* Disable CRC */
wbcir_select_bank(data, WBCIR_BANK_6);
outb(0x20, data->sbase + WBCIR_REG_SP3_IRCR3);
/* Set RX/TX (de)modulation freq, not really used */
wbcir_select_bank(data, WBCIR_BANK_7);
outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC);
outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC);
/* Set invert and pin direction */
if (invert)
outb(0x10, data->sbase + WBCIR_REG_SP3_IRCFG4);
else
outb(0x00, data->sbase + WBCIR_REG_SP3_IRCFG4);
/* Set FIFO thresholds (RX = 8, TX = 3), reset RX/TX */
wbcir_select_bank(data, WBCIR_BANK_0);
outb(0x97, data->sbase + WBCIR_REG_SP3_FCR);
/* Clear AUX status bits */
outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
/* Enable interrupts */
outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
return 0; return 0;
......
...@@ -68,10 +68,6 @@ module_param(post_interrupt_delay, int, 0644); ...@@ -68,10 +68,6 @@ module_param(post_interrupt_delay, int, 0644);
MODULE_PARM_DESC(post_interrupt_delay, MODULE_PARM_DESC(post_interrupt_delay,
"delay (ms) before recal after recal interrupt detected"); "delay (ms) before recal after recal interrupt detected");
static int autorecal = 1;
module_param(autorecal, int, 0644);
MODULE_PARM_DESC(autorecal, "enable recalibration in the driver");
/* /*
* When the touchpad gets ultra-sensitive, one can keep their finger 1/2" * When the touchpad gets ultra-sensitive, one can keep their finger 1/2"
* above the pad and still have it send packets. This causes a jump cursor * above the pad and still have it send packets. This causes a jump cursor
......
...@@ -186,7 +186,7 @@ static void __devexit pcips2_remove(struct pci_dev *dev) ...@@ -186,7 +186,7 @@ static void __devexit pcips2_remove(struct pci_dev *dev)
pci_disable_device(dev); pci_disable_device(dev);
} }
static struct pci_device_id pcips2_ids[] = { static const struct pci_device_id pcips2_ids[] = {
{ {
.vendor = 0x14f2, /* MOBILITY */ .vendor = 0x14f2, /* MOBILITY */
.device = 0x0123, /* Keyboard */ .device = 0x0123, /* Keyboard */
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/serio.h> #include <linux/serio.h>
...@@ -119,11 +121,10 @@ static int serio_bind_driver(struct serio *serio, struct serio_driver *drv) ...@@ -119,11 +121,10 @@ static int serio_bind_driver(struct serio *serio, struct serio_driver *drv)
error = device_bind_driver(&serio->dev); error = device_bind_driver(&serio->dev);
if (error) { if (error) {
printk(KERN_WARNING dev_warn(&serio->dev,
"serio: device_bind_driver() failed " "device_bind_driver() failed for %s (%s) and %s, error: %d\n",
"for %s (%s) and %s, error: %d\n", serio->phys, serio->name,
serio->phys, serio->name, drv->description, error);
drv->description, error);
serio_disconnect_driver(serio); serio_disconnect_driver(serio);
serio->dev.driver = NULL; serio->dev.driver = NULL;
return error; return error;
...@@ -138,9 +139,9 @@ static void serio_find_driver(struct serio *serio) ...@@ -138,9 +139,9 @@ static void serio_find_driver(struct serio *serio)
error = device_attach(&serio->dev); error = device_attach(&serio->dev);
if (error < 0) if (error < 0)
printk(KERN_WARNING dev_warn(&serio->dev,
"serio: device_attach() failed for %s (%s), error: %d\n", "device_attach() failed for %s (%s), error: %d\n",
serio->phys, serio->name, error); serio->phys, serio->name, error);
} }
...@@ -194,17 +195,14 @@ static int serio_queue_event(void *object, struct module *owner, ...@@ -194,17 +195,14 @@ static int serio_queue_event(void *object, struct module *owner,
event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC);
if (!event) { if (!event) {
printk(KERN_ERR pr_err("Not enough memory to queue event %d\n", event_type);
"serio: Not enough memory to queue event %d\n",
event_type);
retval = -ENOMEM; retval = -ENOMEM;
goto out; goto out;
} }
if (!try_module_get(owner)) { if (!try_module_get(owner)) {
printk(KERN_WARNING pr_warning("Can't get module reference, dropping event %d\n",
"serio: Can't get module reference, dropping event %d\n", event_type);
event_type);
kfree(event); kfree(event);
retval = -EINVAL; retval = -EINVAL;
goto out; goto out;
...@@ -230,14 +228,12 @@ static void serio_free_event(struct serio_event *event) ...@@ -230,14 +228,12 @@ static void serio_free_event(struct serio_event *event)
static void serio_remove_duplicate_events(struct serio_event *event) static void serio_remove_duplicate_events(struct serio_event *event)
{ {
struct list_head *node, *next; struct serio_event *e, *next;
struct serio_event *e;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&serio_event_lock, flags); spin_lock_irqsave(&serio_event_lock, flags);
list_for_each_safe(node, next, &serio_event_list) { list_for_each_entry_safe(e, next, &serio_event_list, node) {
e = list_entry(node, struct serio_event, node);
if (event->object == e->object) { if (event->object == e->object) {
/* /*
* If this event is of different type we should not * If this event is of different type we should not
...@@ -247,7 +243,7 @@ static void serio_remove_duplicate_events(struct serio_event *event) ...@@ -247,7 +243,7 @@ static void serio_remove_duplicate_events(struct serio_event *event)
if (event->type != e->type) if (event->type != e->type)
break; break;
list_del_init(node); list_del_init(&e->node);
serio_free_event(e); serio_free_event(e);
} }
} }
...@@ -258,23 +254,18 @@ static void serio_remove_duplicate_events(struct serio_event *event) ...@@ -258,23 +254,18 @@ static void serio_remove_duplicate_events(struct serio_event *event)
static struct serio_event *serio_get_event(void) static struct serio_event *serio_get_event(void)
{ {
struct serio_event *event; struct serio_event *event = NULL;
struct list_head *node;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&serio_event_lock, flags); spin_lock_irqsave(&serio_event_lock, flags);
if (list_empty(&serio_event_list)) { if (!list_empty(&serio_event_list)) {
spin_unlock_irqrestore(&serio_event_lock, flags); event = list_first_entry(&serio_event_list,
return NULL; struct serio_event, node);
list_del_init(&event->node);
} }
node = serio_event_list.next;
event = list_entry(node, struct serio_event, node);
list_del_init(node);
spin_unlock_irqrestore(&serio_event_lock, flags); spin_unlock_irqrestore(&serio_event_lock, flags);
return event; return event;
} }
...@@ -287,29 +278,27 @@ static void serio_handle_event(void) ...@@ -287,29 +278,27 @@ static void serio_handle_event(void)
while ((event = serio_get_event())) { while ((event = serio_get_event())) {
switch (event->type) { switch (event->type) {
case SERIO_REGISTER_PORT:
serio_add_port(event->object);
break;
case SERIO_RECONNECT_PORT: case SERIO_REGISTER_PORT:
serio_reconnect_port(event->object); serio_add_port(event->object);
break; break;
case SERIO_RESCAN_PORT: case SERIO_RECONNECT_PORT:
serio_disconnect_port(event->object); serio_reconnect_port(event->object);
serio_find_driver(event->object); break;
break;
case SERIO_RECONNECT_CHAIN: case SERIO_RESCAN_PORT:
serio_reconnect_chain(event->object); serio_disconnect_port(event->object);
break; serio_find_driver(event->object);
break;
case SERIO_ATTACH_DRIVER: case SERIO_RECONNECT_CHAIN:
serio_attach_driver(event->object); serio_reconnect_chain(event->object);
break; break;
default: case SERIO_ATTACH_DRIVER:
break; serio_attach_driver(event->object);
break;
} }
serio_remove_duplicate_events(event); serio_remove_duplicate_events(event);
...@@ -325,16 +314,14 @@ static void serio_handle_event(void) ...@@ -325,16 +314,14 @@ static void serio_handle_event(void)
*/ */
static void serio_remove_pending_events(void *object) static void serio_remove_pending_events(void *object)
{ {
struct list_head *node, *next; struct serio_event *event, *next;
struct serio_event *event;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&serio_event_lock, flags); spin_lock_irqsave(&serio_event_lock, flags);
list_for_each_safe(node, next, &serio_event_list) { list_for_each_entry_safe(event, next, &serio_event_list, node) {
event = list_entry(node, struct serio_event, node);
if (event->object == object) { if (event->object == object) {
list_del_init(node); list_del_init(&event->node);
serio_free_event(event); serio_free_event(event);
} }
} }
...@@ -380,7 +367,6 @@ static int serio_thread(void *nothing) ...@@ -380,7 +367,6 @@ static int serio_thread(void *nothing)
kthread_should_stop() || !list_empty(&serio_event_list)); kthread_should_stop() || !list_empty(&serio_event_list));
} while (!kthread_should_stop()); } while (!kthread_should_stop());
printk(KERN_DEBUG "serio: kseriod exiting\n");
return 0; return 0;
} }
...@@ -445,6 +431,11 @@ static struct attribute_group serio_id_attr_group = { ...@@ -445,6 +431,11 @@ static struct attribute_group serio_id_attr_group = {
.attrs = serio_device_id_attrs, .attrs = serio_device_id_attrs,
}; };
static const struct attribute_group *serio_device_attr_groups[] = {
&serio_id_attr_group,
NULL
};
static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{ {
struct serio *serio = to_serio_port(dev); struct serio *serio = to_serio_port(dev);
...@@ -532,6 +523,7 @@ static void serio_init_port(struct serio *serio) ...@@ -532,6 +523,7 @@ static void serio_init_port(struct serio *serio)
(long)atomic_inc_return(&serio_no) - 1); (long)atomic_inc_return(&serio_no) - 1);
serio->dev.bus = &serio_bus; serio->dev.bus = &serio_bus;
serio->dev.release = serio_release_port; serio->dev.release = serio_release_port;
serio->dev.groups = serio_device_attr_groups;
if (serio->parent) { if (serio->parent) {
serio->dev.parent = &serio->parent->dev; serio->dev.parent = &serio->parent->dev;
serio->depth = serio->parent->depth + 1; serio->depth = serio->parent->depth + 1;
...@@ -555,21 +547,15 @@ static void serio_add_port(struct serio *serio) ...@@ -555,21 +547,15 @@ static void serio_add_port(struct serio *serio)
} }
list_add_tail(&serio->node, &serio_list); list_add_tail(&serio->node, &serio_list);
if (serio->start) if (serio->start)
serio->start(serio); serio->start(serio);
error = device_add(&serio->dev); error = device_add(&serio->dev);
if (error) if (error)
printk(KERN_ERR dev_err(&serio->dev,
"serio: device_add() failed for %s (%s), error: %d\n", "device_add() failed for %s (%s), error: %d\n",
serio->phys, serio->name, error); serio->phys, serio->name, error);
else {
serio->registered = true;
error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group);
if (error)
printk(KERN_ERR
"serio: sysfs_create_group() failed for %s (%s), error: %d\n",
serio->phys, serio->name, error);
}
} }
/* /*
...@@ -596,11 +582,8 @@ static void serio_destroy_port(struct serio *serio) ...@@ -596,11 +582,8 @@ static void serio_destroy_port(struct serio *serio)
serio->parent = NULL; serio->parent = NULL;
} }
if (serio->registered) { if (device_is_registered(&serio->dev))
sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group);
device_del(&serio->dev); device_del(&serio->dev);
serio->registered = false;
}
list_del_init(&serio->node); list_del_init(&serio->node);
serio_remove_pending_events(serio); serio_remove_pending_events(serio);
...@@ -798,9 +781,8 @@ static void serio_attach_driver(struct serio_driver *drv) ...@@ -798,9 +781,8 @@ static void serio_attach_driver(struct serio_driver *drv)
error = driver_attach(&drv->driver); error = driver_attach(&drv->driver);
if (error) if (error)
printk(KERN_WARNING pr_warning("driver_attach() failed for %s with error %d\n",
"serio: driver_attach() failed for %s with error %d\n", drv->driver.name, error);
drv->driver.name, error);
} }
int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name) int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name)
...@@ -820,8 +802,7 @@ int __serio_register_driver(struct serio_driver *drv, struct module *owner, cons ...@@ -820,8 +802,7 @@ int __serio_register_driver(struct serio_driver *drv, struct module *owner, cons
error = driver_register(&drv->driver); error = driver_register(&drv->driver);
if (error) { if (error) {
printk(KERN_ERR pr_err("driver_register() failed for %s, error: %d\n",
"serio: driver_register() failed for %s, error: %d\n",
drv->driver.name, error); drv->driver.name, error);
return error; return error;
} }
...@@ -987,7 +968,7 @@ irqreturn_t serio_interrupt(struct serio *serio, ...@@ -987,7 +968,7 @@ irqreturn_t serio_interrupt(struct serio *serio,
if (likely(serio->drv)) { if (likely(serio->drv)) {
ret = serio->drv->interrupt(serio, data, dfl); ret = serio->drv->interrupt(serio, data, dfl);
} else if (!dfl && serio->registered) { } else if (!dfl && device_is_registered(&serio->dev)) {
serio_rescan(serio); serio_rescan(serio);
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
} }
...@@ -1018,7 +999,7 @@ static int __init serio_init(void) ...@@ -1018,7 +999,7 @@ static int __init serio_init(void)
error = bus_register(&serio_bus); error = bus_register(&serio_bus);
if (error) { if (error) {
printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error); pr_err("Failed to register serio bus, error: %d\n", error);
return error; return error;
} }
...@@ -1026,7 +1007,7 @@ static int __init serio_init(void) ...@@ -1026,7 +1007,7 @@ static int __init serio_init(void)
if (IS_ERR(serio_task)) { if (IS_ERR(serio_task)) {
bus_unregister(&serio_bus); bus_unregister(&serio_bus);
error = PTR_ERR(serio_task); error = PTR_ERR(serio_task);
printk(KERN_ERR "serio: Failed to start kseriod, error: %d\n", error); pr_err("Failed to start kseriod, error: %d\n", error);
return error; return error;
} }
......
...@@ -270,7 +270,7 @@ static int __devinit xps2_of_probe(struct of_device *ofdev, ...@@ -270,7 +270,7 @@ static int __devinit xps2_of_probe(struct of_device *ofdev,
drvdata->irq = r_irq.start; drvdata->irq = r_irq.start;
phys_addr = r_mem.start; phys_addr = r_mem.start;
remap_size = r_mem.end - r_mem.start + 1; remap_size = resource_size(&r_mem);
if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) { if (!request_mem_region(phys_addr, remap_size, DRIVER_NAME)) {
dev_err(dev, "Couldn't lock memory region at 0x%08llX\n", dev_err(dev, "Couldn't lock memory region at 0x%08llX\n",
(unsigned long long)phys_addr); (unsigned long long)phys_addr);
...@@ -344,7 +344,7 @@ static int __devexit xps2_of_remove(struct of_device *of_dev) ...@@ -344,7 +344,7 @@ static int __devexit xps2_of_remove(struct of_device *of_dev)
if (of_address_to_resource(of_dev->node, 0, &r_mem)) if (of_address_to_resource(of_dev->node, 0, &r_mem))
dev_err(dev, "invalid address\n"); dev_err(dev, "invalid address\n");
else else
release_mem_region(r_mem.start, r_mem.end - r_mem.start + 1); release_mem_region(r_mem.start, resource_size(&r_mem));
kfree(drvdata); kfree(drvdata);
...@@ -354,7 +354,7 @@ static int __devexit xps2_of_remove(struct of_device *of_dev) ...@@ -354,7 +354,7 @@ static int __devexit xps2_of_remove(struct of_device *of_dev)
} }
/* Match table for of_platform binding */ /* Match table for of_platform binding */
static struct of_device_id xps2_of_match[] __devinitdata = { static const struct of_device_id xps2_of_match[] __devinitconst = {
{ .compatible = "xlnx,xps-ps2-1.00.a", }, { .compatible = "xlnx,xps-ps2-1.00.a", },
{ /* end of list */ }, { /* end of list */ },
}; };
......
...@@ -92,7 +92,7 @@ Scott Hill shill@gtcocalcomp.com ...@@ -92,7 +92,7 @@ Scott Hill shill@gtcocalcomp.com
/* DATA STRUCTURES */ /* DATA STRUCTURES */
/* Device table */ /* Device table */
static struct usb_device_id gtco_usbid_table [] = { static const struct usb_device_id gtco_usbid_table[] = {
{ USB_DEVICE(VENDOR_ID_GTCO, PID_400) }, { USB_DEVICE(VENDOR_ID_GTCO, PID_400) },
{ USB_DEVICE(VENDOR_ID_GTCO, PID_401) }, { USB_DEVICE(VENDOR_ID_GTCO, PID_401) },
{ USB_DEVICE(VENDOR_ID_GTCO, PID_1000) }, { USB_DEVICE(VENDOR_ID_GTCO, PID_1000) },
......
...@@ -85,6 +85,7 @@ ...@@ -85,6 +85,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/usb/input.h> #include <linux/usb/input.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
...@@ -120,6 +121,8 @@ struct wacom_combo { ...@@ -120,6 +121,8 @@ struct wacom_combo {
struct urb *urb; struct urb *urb;
}; };
extern const struct usb_device_id wacom_ids[];
extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo); extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo);
extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data); extern void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data);
extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data); extern void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data);
...@@ -142,7 +145,5 @@ extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wa ...@@ -142,7 +145,5 @@ extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wa
extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
extern __u16 wacom_le16_to_cpu(unsigned char *data); extern __u16 wacom_le16_to_cpu(unsigned char *data);
extern __u16 wacom_be16_to_cpu(unsigned char *data); extern __u16 wacom_be16_to_cpu(unsigned char *data);
extern struct wacom_features *get_wacom_feature(const struct usb_device_id *id);
extern const struct usb_device_id *get_device_table(void);
#endif #endif
...@@ -211,7 +211,8 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) ...@@ -211,7 +211,8 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) | BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) |
BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2);
input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); input_set_abs_params(input_dev, ABS_DISTANCE,
0, wacom_wac->features.distance_max, 0, 0);
} }
void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
...@@ -261,7 +262,8 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) ...@@ -261,7 +262,8 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) |
BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) |
BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2);
input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); input_set_abs_params(input_dev, ABS_DISTANCE,
0, wacom_wac->features.distance_max, 0, 0);
input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0); input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0);
...@@ -282,17 +284,19 @@ void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) ...@@ -282,17 +284,19 @@ void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac) void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{ {
if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP || struct wacom_features *features = &wacom_wac->features;
wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) {
input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->x_phy, 0, 0); if (features->device_type == BTN_TOOL_DOUBLETAP ||
input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->y_phy, 0, 0); features->device_type == BTN_TOOL_TRIPLETAP) {
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); input_set_abs_params(input_dev, ABS_RX, 0, features->x_phy, 0, 0);
input_set_abs_params(input_dev, ABS_RY, 0, features->y_phy, 0, 0);
__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
} }
} }
void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac) void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{ {
if (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) { if (wacom_wac->features.device_type == BTN_TOOL_TRIPLETAP) {
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP); input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP);
input_dev->evbit[0] |= BIT_MASK(EV_MSC); input_dev->evbit[0] |= BIT_MASK(EV_MSC);
input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
...@@ -532,21 +536,38 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -532,21 +536,38 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
struct wacom_wac *wacom_wac; struct wacom_wac *wacom_wac;
struct wacom_features *features; struct wacom_features *features;
struct input_dev *input_dev; struct input_dev *input_dev;
int error = -ENOMEM; int error;
if (!id->driver_info)
return -EINVAL;
wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL);
input_dev = input_allocate_device(); input_dev = input_allocate_device();
if (!wacom || !input_dev || !wacom_wac) if (!wacom || !input_dev || !wacom_wac) {
error = -ENOMEM;
goto fail1; goto fail1;
}
wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX, GFP_KERNEL, &wacom->data_dma); wacom_wac->features = *((struct wacom_features *)id->driver_info);
if (!wacom_wac->data) features = &wacom_wac->features;
if (features->pktlen > WACOM_PKGLEN_MAX) {
error = -EINVAL;
goto fail1; goto fail1;
}
wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX,
GFP_KERNEL, &wacom->data_dma);
if (!wacom_wac->data) {
error = -ENOMEM;
goto fail1;
}
wacom->irq = usb_alloc_urb(0, GFP_KERNEL); wacom->irq = usb_alloc_urb(0, GFP_KERNEL);
if (!wacom->irq) if (!wacom->irq) {
error = -ENOMEM;
goto fail2; goto fail2;
}
wacom->usbdev = dev; wacom->usbdev = dev;
wacom->dev = input_dev; wacom->dev = input_dev;
...@@ -555,11 +576,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -555,11 +576,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
usb_make_path(dev, wacom->phys, sizeof(wacom->phys)); usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
wacom_wac->features = features = get_wacom_feature(id);
BUG_ON(features->pktlen > WACOM_PKGLEN_MAX);
input_dev->name = wacom_wac->features->name;
wacom->wacom_wac = wacom_wac;
usb_to_input_id(dev, &input_dev->id); usb_to_input_id(dev, &input_dev->id);
input_dev->dev.parent = &intf->dev; input_dev->dev.parent = &intf->dev;
...@@ -576,6 +592,19 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -576,6 +592,19 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
if (error) if (error)
goto fail2; goto fail2;
strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name));
if (features->type == TABLETPC || features->type == TABLETPC2FG) {
/* Append the device type to the name */
strlcat(wacom_wac->name,
features->device_type == BTN_TOOL_PEN ?
" Pen" : " Finger",
sizeof(wacom_wac->name));
}
input_dev->name = wacom_wac->name;
wacom->wacom_wac = wacom_wac;
input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH); input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH);
...@@ -640,7 +669,7 @@ static int wacom_suspend(struct usb_interface *intf, pm_message_t message) ...@@ -640,7 +669,7 @@ static int wacom_suspend(struct usb_interface *intf, pm_message_t message)
static int wacom_resume(struct usb_interface *intf) static int wacom_resume(struct usb_interface *intf)
{ {
struct wacom *wacom = usb_get_intfdata(intf); struct wacom *wacom = usb_get_intfdata(intf);
struct wacom_features *features = wacom->wacom_wac->features; struct wacom_features *features = &wacom->wacom_wac->features;
int rv; int rv;
mutex_lock(&wacom->lock); mutex_lock(&wacom->lock);
...@@ -663,6 +692,7 @@ static int wacom_reset_resume(struct usb_interface *intf) ...@@ -663,6 +692,7 @@ static int wacom_reset_resume(struct usb_interface *intf)
static struct usb_driver wacom_driver = { static struct usb_driver wacom_driver = {
.name = "wacom", .name = "wacom",
.id_table = wacom_ids,
.probe = wacom_probe, .probe = wacom_probe,
.disconnect = wacom_disconnect, .disconnect = wacom_disconnect,
.suspend = wacom_suspend, .suspend = wacom_suspend,
...@@ -674,7 +704,7 @@ static struct usb_driver wacom_driver = { ...@@ -674,7 +704,7 @@ static struct usb_driver wacom_driver = {
static int __init wacom_init(void) static int __init wacom_init(void)
{ {
int result; int result;
wacom_driver.id_table = get_device_table();
result = usb_register(&wacom_driver); result = usb_register(&wacom_driver);
if (result == 0) if (result == 0)
printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
......
This diff is collapsed.
...@@ -15,11 +15,11 @@ ...@@ -15,11 +15,11 @@
/* packet length for individual models */ /* packet length for individual models */
#define WACOM_PKGLEN_PENPRTN 7 #define WACOM_PKGLEN_PENPRTN 7
#define WACOM_PKGLEN_GRAPHIRE 8 #define WACOM_PKGLEN_GRAPHIRE 8
#define WACOM_PKGLEN_BBFUN 9 #define WACOM_PKGLEN_BBFUN 9
#define WACOM_PKGLEN_INTUOS 10 #define WACOM_PKGLEN_INTUOS 10
#define WACOM_PKGLEN_PENABLED 8 #define WACOM_PKGLEN_PENABLED 8
#define WACOM_PKGLEN_TPC1FG 5 #define WACOM_PKGLEN_TPC1FG 5
#define WACOM_PKGLEN_TPC2FG 14 #define WACOM_PKGLEN_TPC2FG 14
/* device IDs */ /* device IDs */
#define STYLUS_DEVICE_ID 0x02 #define STYLUS_DEVICE_ID 0x02
...@@ -58,7 +58,7 @@ enum { ...@@ -58,7 +58,7 @@ enum {
}; };
struct wacom_features { struct wacom_features {
char *name; const char *name;
int pktlen; int pktlen;
int x_max; int x_max;
int y_max; int y_max;
...@@ -73,11 +73,12 @@ struct wacom_features { ...@@ -73,11 +73,12 @@ struct wacom_features {
}; };
struct wacom_wac { struct wacom_wac {
char name[64];
unsigned char *data; unsigned char *data;
int tool[2]; int tool[2];
int id[2]; int id[2];
__u32 serial[2]; __u32 serial[2];
struct wacom_features *features; struct wacom_features features;
}; };
#endif #endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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