提交 d6879837 编写于 作者: L 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:
  Input: remove scan_keyb driver
  Input: i8042 - fix AUX IRQ delivery check
  Input: wistron - add support for Fujitsu-Siemens Amilo D88x0
  Input: inport - use correct config option for ATIXL
  Input: HIL - handle erros from input_register_device()
  Input: tsdev - schedule removal
  Input: add Atlas button driver
  Input: ads7846 - be more compatible with the hwmon framework
  Input: ads7846 - detect pen up from GPIO state
  Input: ads7846 - select correct SPI mode
  Input: ads7846 - switch to using hrtimer
  Input: ads7846 - optionally leave Vref on during differential measurements
  Input: ads7846 - pluggable filtering logic
  Input: gpio-keys - keyboard driver for GPIO buttons
  Input: hid-ff - add support for Logitech Momo racing wheel
  Input: i8042 - really suppress ACK/NAK during panic blink
  Input: pc110pad - return proper error
...@@ -319,3 +319,18 @@ Why: In kernel tree version of driver is unmaintained. Sk98lin driver ...@@ -319,3 +319,18 @@ Why: In kernel tree version of driver is unmaintained. Sk98lin driver
replaced by the skge driver. replaced by the skge driver.
Who: Stephen Hemminger <shemminger@osdl.org> Who: Stephen Hemminger <shemminger@osdl.org>
---------------------------
What: Compaq touchscreen device emulation
When: Oct 2007
Files: drivers/input/tsdev.c
Why: The code says it was obsolete when it was written in 2001.
tslib is a userspace library which does anything tsdev can do and
much more besides in userspace where this code belongs. There is no
longer any need for tsdev and applications should have converted to
use tslib by now.
The name "tsdev" is also extremely confusing and lots of people have
it loaded when they don't need/use it.
Who: Richard Purdie <rpurdie@rpsys.net>
---------------------------
/*
* $Id: scan_keyb.c,v 1.2 2000/07/04 06:24:42 yaegashi Exp $
* Copyright (C) 2000 YAEGASHI Takeshi
* Generic scan keyboard driver
*/
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/mm.h>
#include <linux/signal.h>
#include <linux/init.h>
#include <linux/kbd_ll.h>
#include <linux/delay.h>
#include <linux/random.h>
#include <linux/poll.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/kbd_kern.h>
#include <linux/timer.h>
#define SCANHZ (HZ/20)
struct scan_keyboard {
struct scan_keyboard *next;
int (*scan)(unsigned char *buffer);
const unsigned char *table;
unsigned char *s0, *s1;
int length;
};
static int scan_jiffies=0;
static struct scan_keyboard *keyboards=NULL;
struct timer_list scan_timer;
static void check_kbd(const unsigned char *table,
unsigned char *new, unsigned char *old, int length)
{
int need_tasklet_schedule=0;
unsigned int xor, bit;
while(length-->0) {
if((xor=*new^*old)==0) {
table+=8;
}
else {
for(bit=0x01; bit<0x100; bit<<=1) {
if(xor&bit) {
handle_scancode(*table, !(*new&bit));
need_tasklet_schedule=1;
#if 0
printk("0x%x %s\n", *table, (*new&bit)?"released":"pressed");
#endif
}
table++;
}
}
new++; old++;
}
if(need_tasklet_schedule)
tasklet_schedule(&keyboard_tasklet);
}
static void scan_kbd(unsigned long dummy)
{
struct scan_keyboard *kbd;
scan_jiffies++;
for(kbd=keyboards; kbd!=NULL; kbd=kbd->next) {
if(scan_jiffies&1) {
if(!kbd->scan(kbd->s0))
check_kbd(kbd->table,
kbd->s0, kbd->s1, kbd->length);
else
memcpy(kbd->s0, kbd->s1, kbd->length);
}
else {
if(!kbd->scan(kbd->s1))
check_kbd(kbd->table,
kbd->s1, kbd->s0, kbd->length);
else
memcpy(kbd->s1, kbd->s0, kbd->length);
}
}
init_timer(&scan_timer);
scan_timer.expires = jiffies + SCANHZ;
scan_timer.data = 0;
scan_timer.function = scan_kbd;
add_timer(&scan_timer);
}
int register_scan_keyboard(int (*scan)(unsigned char *buffer),
const unsigned char *table,
int length)
{
struct scan_keyboard *kbd;
kbd = kmalloc(sizeof(struct scan_keyboard), GFP_KERNEL);
if (kbd == NULL)
goto error_out;
kbd->scan=scan;
kbd->table=table;
kbd->length=length;
kbd->s0 = kmalloc(length, GFP_KERNEL);
if (kbd->s0 == NULL)
goto error_free_kbd;
kbd->s1 = kmalloc(length, GFP_KERNEL);
if (kbd->s1 == NULL)
goto error_free_s0;
memset(kbd->s0, -1, kbd->length);
memset(kbd->s1, -1, kbd->length);
kbd->next=keyboards;
keyboards=kbd;
return 0;
error_free_s0:
kfree(kbd->s0);
error_free_kbd:
kfree(kbd);
error_out:
return -ENOMEM;
}
void __init scan_kbd_init(void)
{
init_timer(&scan_timer);
scan_timer.expires = jiffies + SCANHZ;
scan_timer.data = 0;
scan_timer.function = scan_kbd;
add_timer(&scan_timer);
printk(KERN_INFO "Generic scan keyboard driver initialized\n");
}
#ifndef __DRIVER_CHAR_SCAN_KEYB_H
#define __DRIVER_CHAR_SCAN_KEYB_H
/*
* $Id: scan_keyb.h,v 1.1 2000/06/10 21:45:30 yaegashi Exp $
* Copyright (C) 2000 YAEGASHI Takeshi
* Generic scan keyboard driver
*/
int register_scan_keyboard(int (*scan)(unsigned char *buffer),
const unsigned char *table,
int length);
void __init scan_kbd_init(void);
#endif
...@@ -135,12 +135,12 @@ config KEYBOARD_STOWAWAY ...@@ -135,12 +135,12 @@ config KEYBOARD_STOWAWAY
config KEYBOARD_CORGI config KEYBOARD_CORGI
tristate "Corgi keyboard" tristate "Corgi keyboard"
depends on PXA_SHARPSL depends on PXA_SHARPSL
default y 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.
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.
config KEYBOARD_SPITZ config KEYBOARD_SPITZ
...@@ -214,4 +214,17 @@ config KEYBOARD_AAED2000 ...@@ -214,4 +214,17 @@ config KEYBOARD_AAED2000
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 aaed2000_kbd. module will be called aaed2000_kbd.
config KEYBOARD_GPIO
tristate "Buttons on CPU GPIOs (PXA)"
depends on ARCH_PXA
help
This driver implements support for buttons connected
directly to GPIO pins of PXA CPUs.
Say Y here if your device has buttons connected
directly to GPIO pins of the CPU.
To compile this driver as a module, choose M here: the
module will be called gpio-keys.
endif endif
...@@ -16,6 +16,7 @@ obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o ...@@ -16,6 +16,7 @@ obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o
obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.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_OMAP) += omap-keypad.o obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
/*
* Driver for keys on GPIO lines capable of generating interrupts.
*
* Copyright 2005 Phil Blundell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/hardware.h>
#include <asm/hardware/gpio_keys.h>
static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
{
int i;
struct platform_device *pdev = dev_id;
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
struct input_dev *input = platform_get_drvdata(pdev);
for (i = 0; i < pdata->nbuttons; i++) {
int gpio = pdata->buttons[i].gpio;
if (irq == IRQ_GPIO(gpio)) {
int state = ((GPLR(gpio) & GPIO_bit(gpio)) ? 1 : 0) ^ (pdata->buttons[i].active_low);
input_report_key(input, pdata->buttons[i].keycode, state);
input_sync(input);
}
}
return IRQ_HANDLED;
}
static int __devinit gpio_keys_probe(struct platform_device *pdev)
{
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
struct input_dev *input;
int i, error;
input = input_allocate_device();
if (!input)
return -ENOMEM;
platform_set_drvdata(pdev, input);
input->evbit[0] = BIT(EV_KEY);
input->name = pdev->name;
input->phys = "gpio-keys/input0";
input->cdev.dev = &pdev->dev;
input->private = pdata;
input->id.bustype = BUS_HOST;
input->id.vendor = 0x0001;
input->id.product = 0x0001;
input->id.version = 0x0100;
for (i = 0; i < pdata->nbuttons; i++) {
int code = pdata->buttons[i].keycode;
int irq = IRQ_GPIO(pdata->buttons[i].gpio);
set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
error = request_irq(irq, gpio_keys_isr, SA_SAMPLE_RANDOM,
pdata->buttons[i].desc ? pdata->buttons[i].desc : "gpio_keys",
pdev);
if (error) {
printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n", irq, ret);
goto fail;
}
set_bit(code, input->keybit);
}
error = input_register_device(input);
if (error) {
printk(KERN_ERR "Unable to register gpio-keys input device\n");
goto fail;
}
return 0;
fail:
for (i = i - 1; i >= 0; i--)
free_irq(IRQ_GPIO(pdata->buttons[i].gpio), pdev);
input_free_device(input);
return error;
}
static int __devexit gpio_keys_remove(struct platform_device *pdev)
{
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
struct input_dev *input = platform_get_drvdata(pdev);
int i;
for (i = 0; i < pdata->nbuttons; i++) {
int irq = IRQ_GPIO(pdata->buttons[i].gpio);
free_irq(irq, pdev);
}
input_unregister_device(input);
return 0;
}
struct platform_driver gpio_keys_device_driver = {
.probe = gpio_keys_probe,
.remove = __devexit_p(gpio_keys_remove),
.driver = {
.name = "gpio-keys",
}
};
static int __init gpio_keys_init(void)
{
return platform_driver_register(&gpio_keys_device_driver);
}
static void __exit gpio_keys_exit(void)
{
platform_driver_unregister(&gpio_keys_device_driver);
}
module_init(gpio_keys_init);
module_exit(gpio_keys_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>");
MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs");
...@@ -6,10 +6,10 @@ ...@@ -6,10 +6,10 @@
* Copyright (C) 1999-2006 Helge Deller <deller@gmx.de> * Copyright (C) 1999-2006 Helge Deller <deller@gmx.de>
* *
* Very basic HP Human Interface Loop (HIL) driver. * Very basic HP Human Interface Loop (HIL) driver.
* This driver handles the keyboard on HP300 (m68k) and on some * This driver handles the keyboard on HP300 (m68k) and on some
* HP700 (parisc) series machines. * HP700 (parisc) series machines.
* *
* *
* This file is subject to the terms and conditions of the GNU General Public * This file is subject to the terms and conditions of the GNU General Public
* License version 2. See the file COPYING in the main directory of this * License version 2. See the file COPYING in the main directory of this
* archive for more details. * archive for more details.
...@@ -64,9 +64,9 @@ MODULE_LICENSE("GPL v2"); ...@@ -64,9 +64,9 @@ MODULE_LICENSE("GPL v2");
#endif #endif
/* HIL helper functions */ /* HIL helper functions */
#define hil_busy() (hil_readb(HILBASE + HIL_CMD) & HIL_BUSY) #define hil_busy() (hil_readb(HILBASE + HIL_CMD) & HIL_BUSY)
#define hil_data_available() (hil_readb(HILBASE + HIL_CMD) & HIL_DATA_RDY) #define hil_data_available() (hil_readb(HILBASE + HIL_CMD) & HIL_DATA_RDY)
#define hil_status() (hil_readb(HILBASE + HIL_CMD)) #define hil_status() (hil_readb(HILBASE + HIL_CMD))
...@@ -75,7 +75,7 @@ MODULE_LICENSE("GPL v2"); ...@@ -75,7 +75,7 @@ MODULE_LICENSE("GPL v2");
#define hil_write_data(x) do { hil_writeb((x), HILBASE + HIL_DATA); } while (0) #define hil_write_data(x) do { hil_writeb((x), HILBASE + HIL_DATA); } while (0)
/* HIL constants */ /* HIL constants */
#define HIL_BUSY 0x02 #define HIL_BUSY 0x02
#define HIL_DATA_RDY 0x01 #define HIL_DATA_RDY 0x01
...@@ -86,10 +86,10 @@ MODULE_LICENSE("GPL v2"); ...@@ -86,10 +86,10 @@ MODULE_LICENSE("GPL v2");
#define HIL_INTON 0x5C /* Turn on interrupts. */ #define HIL_INTON 0x5C /* Turn on interrupts. */
#define HIL_INTOFF 0x5D /* Turn off interrupts. */ #define HIL_INTOFF 0x5D /* Turn off interrupts. */
#define HIL_READKBDSADR 0xF9 #define HIL_READKBDSADR 0xF9
#define HIL_WRITEKBDSADR 0xE9 #define HIL_WRITEKBDSADR 0xE9
static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] = static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] =
{ HIL_KEYCODES_SET1 }; { HIL_KEYCODES_SET1 };
/* HIL structure */ /* HIL structure */
...@@ -97,11 +97,11 @@ static struct { ...@@ -97,11 +97,11 @@ static struct {
struct input_dev *dev; struct input_dev *dev;
unsigned int curdev; unsigned int curdev;
unsigned char s; unsigned char s;
unsigned char c; unsigned char c;
int valid; int valid;
unsigned char data[16]; unsigned char data[16];
unsigned int ptr; unsigned int ptr;
spinlock_t lock; spinlock_t lock;
...@@ -115,7 +115,7 @@ static void poll_finished(void) ...@@ -115,7 +115,7 @@ static void poll_finished(void)
int down; int down;
int key; int key;
unsigned char scode; unsigned char scode;
switch (hil_dev.data[0]) { switch (hil_dev.data[0]) {
case 0x40: case 0x40:
down = (hil_dev.data[1] & 1) == 0; down = (hil_dev.data[1] & 1) == 0;
...@@ -127,6 +127,7 @@ static void poll_finished(void) ...@@ -127,6 +127,7 @@ static void poll_finished(void)
hil_dev.curdev = 0; hil_dev.curdev = 0;
} }
static inline void handle_status(unsigned char s, unsigned char c) static inline void handle_status(unsigned char s, unsigned char c)
{ {
if (c & 0x8) { if (c & 0x8) {
...@@ -143,6 +144,7 @@ static inline void handle_status(unsigned char s, unsigned char c) ...@@ -143,6 +144,7 @@ static inline void handle_status(unsigned char s, unsigned char c)
} }
} }
static inline void handle_data(unsigned char s, unsigned char c) static inline void handle_data(unsigned char s, unsigned char c)
{ {
if (hil_dev.curdev) { if (hil_dev.curdev) {
...@@ -152,13 +154,11 @@ static inline void handle_data(unsigned char s, unsigned char c) ...@@ -152,13 +154,11 @@ static inline void handle_data(unsigned char s, unsigned char c)
} }
/* /* handle HIL interrupts */
* Handle HIL interrupts.
*/
static irqreturn_t hil_interrupt(int irq, void *handle) static irqreturn_t hil_interrupt(int irq, void *handle)
{ {
unsigned char s, c; unsigned char s, c;
s = hil_status(); s = hil_status();
c = hil_read_data(); c = hil_read_data();
...@@ -179,10 +179,8 @@ static irqreturn_t hil_interrupt(int irq, void *handle) ...@@ -179,10 +179,8 @@ static irqreturn_t hil_interrupt(int irq, void *handle)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
/*
* Send a command to the HIL
*/
/* send a command to the HIL */
static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len) static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len)
{ {
unsigned long flags; unsigned long flags;
...@@ -200,16 +198,14 @@ static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len) ...@@ -200,16 +198,14 @@ static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len)
} }
/* /* initialise HIL */
* Initialise HIL.
*/
static int __init static int __init
hil_keyb_init(void) hil_keyb_init(void)
{ {
unsigned char c; unsigned char c;
unsigned int i, kbid; unsigned int i, kbid;
wait_queue_head_t hil_wait; wait_queue_head_t hil_wait;
int err;
if (hil_dev.dev) { if (hil_dev.dev) {
return -ENODEV; /* already initialized */ return -ENODEV; /* already initialized */
...@@ -219,15 +215,25 @@ hil_keyb_init(void) ...@@ -219,15 +215,25 @@ hil_keyb_init(void)
if (!hil_dev.dev) if (!hil_dev.dev)
return -ENOMEM; return -ENOMEM;
hil_dev.dev->private = &hil_dev; hil_dev.dev->private = &hil_dev;
#if defined(CONFIG_HP300) #if defined(CONFIG_HP300)
if (!hwreg_present((void *)(HILBASE + HIL_DATA))) if (!hwreg_present((void *)(HILBASE + HIL_DATA))) {
return -ENODEV; printk(KERN_ERR "HIL: hardware register was not found\n");
err = -ENODEV;
request_region(HILBASE+HIL_DATA, 2, "hil"); goto err1;
}
if (!request_region(HILBASE + HIL_DATA, 2, "hil")) {
printk(KERN_ERR "HIL: IOPORT region already used\n");
err = -EIO;
goto err1;
}
#endif #endif
request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id); err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id);
if (err) {
printk(KERN_ERR "HIL: Can't get IRQ\n");
goto err2;
}
/* Turn on interrupts */ /* Turn on interrupts */
hil_do(HIL_INTON, NULL, 0); hil_do(HIL_INTON, NULL, 0);
...@@ -239,47 +245,63 @@ hil_keyb_init(void) ...@@ -239,47 +245,63 @@ hil_keyb_init(void)
init_waitqueue_head(&hil_wait); init_waitqueue_head(&hil_wait);
wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ); wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ);
if (!hil_dev.valid) { if (!hil_dev.valid) {
printk(KERN_WARNING "HIL: timed out, assuming no keyboard present.\n"); printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n");
} }
c = hil_dev.c; c = hil_dev.c;
hil_dev.valid = 0; hil_dev.valid = 0;
if (c == 0) { if (c == 0) {
kbid = -1; kbid = -1;
printk(KERN_WARNING "HIL: no keyboard present.\n"); printk(KERN_WARNING "HIL: no keyboard present\n");
} else { } else {
kbid = ffz(~c); kbid = ffz(~c);
/* printk(KERN_INFO "HIL: keyboard found at id %d\n", kbid); */ printk(KERN_INFO "HIL: keyboard found at id %d\n", kbid);
} }
/* set it to raw mode */ /* set it to raw mode */
c = 0; c = 0;
hil_do(HIL_WRITEKBDSADR, &c, 1); hil_do(HIL_WRITEKBDSADR, &c, 1);
for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++) for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++)
if (hphilkeyb_keycode[i] != KEY_RESERVED) if (hphilkeyb_keycode[i] != KEY_RESERVED)
set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit); set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
hil_dev.dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); hil_dev.dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
hil_dev.dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); hil_dev.dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE;
hil_dev.dev->keycodesize = sizeof(hphilkeyb_keycode[0]); hil_dev.dev->keycodesize= sizeof(hphilkeyb_keycode[0]);
hil_dev.dev->keycode = hphilkeyb_keycode; hil_dev.dev->keycode = hphilkeyb_keycode;
hil_dev.dev->name = "HIL keyboard"; hil_dev.dev->name = "HIL keyboard";
hil_dev.dev->phys = "hpkbd/input0"; hil_dev.dev->phys = "hpkbd/input0";
hil_dev.dev->id.bustype = BUS_HIL; hil_dev.dev->id.bustype = BUS_HIL;
hil_dev.dev->id.vendor = PCI_VENDOR_ID_HP; hil_dev.dev->id.vendor = PCI_VENDOR_ID_HP;
hil_dev.dev->id.product = 0x0001; hil_dev.dev->id.product = 0x0001;
hil_dev.dev->id.version = 0x0010; hil_dev.dev->id.version = 0x0010;
input_register_device(hil_dev.dev); err = input_register_device(hil_dev.dev);
if (err) {
printk(KERN_ERR "HIL: Can't register device\n");
goto err3;
}
printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n", printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n",
hil_dev.dev->name, kbid, HILBASE, HIL_IRQ); hil_dev.dev->name, kbid, HILBASE, HIL_IRQ);
return 0; return 0;
err3:
hil_do(HIL_INTOFF, NULL, 0);
disable_irq(HIL_IRQ);
free_irq(HIL_IRQ, hil_dev.dev_id);
err2:
release_region(HILBASE + HIL_DATA, 2);
err1:
input_free_device(hil_dev.dev);
hil_dev.dev = NULL;
return err;
} }
#if defined(CONFIG_PARISC) #if defined(CONFIG_PARISC)
static int __init static int __init
hil_init_chip(struct parisc_device *dev) hil_init_chip(struct parisc_device *dev)
...@@ -292,7 +314,7 @@ hil_init_chip(struct parisc_device *dev) ...@@ -292,7 +314,7 @@ hil_init_chip(struct parisc_device *dev)
hil_base = dev->hpa.start; hil_base = dev->hpa.start;
hil_irq = dev->irq; hil_irq = dev->irq;
hil_dev.dev_id = dev; hil_dev.dev_id = dev;
printk(KERN_INFO "Found HIL bus at 0x%08lx, IRQ %d\n", hil_base, hil_irq); printk(KERN_INFO "Found HIL bus at 0x%08lx, IRQ %d\n", hil_base, hil_irq);
return hil_keyb_init(); return hil_keyb_init();
...@@ -313,9 +335,6 @@ static struct parisc_driver hil_driver = { ...@@ -313,9 +335,6 @@ static struct parisc_driver hil_driver = {
#endif /* CONFIG_PARISC */ #endif /* CONFIG_PARISC */
static int __init hil_init(void) static int __init hil_init(void)
{ {
#if defined(CONFIG_PARISC) #if defined(CONFIG_PARISC)
...@@ -349,4 +368,3 @@ static void __exit hil_exit(void) ...@@ -349,4 +368,3 @@ static void __exit hil_exit(void)
module_init(hil_init); module_init(hil_init);
module_exit(hil_exit); module_exit(hil_exit);
...@@ -50,6 +50,16 @@ config INPUT_WISTRON_BTNS ...@@ -50,6 +50,16 @@ config INPUT_WISTRON_BTNS
To compile this driver as a module, choose M here: the module will To compile this driver as a module, choose M here: the module will
be called wistron_btns. be called wistron_btns.
config INPUT_ATLAS_BTNS
tristate "x86 Atlas button interface"
depends on X86 && ACPI
help
Say Y here for support of Atlas wallmount touchscreen buttons.
The events will show up as scancodes F1 through F9 via evdev.
To compile this driver as a module, choose M here: the module will
be called atlas_btns.
config INPUT_IXP4XX_BEEPER config INPUT_IXP4XX_BEEPER
tristate "IXP4XX Beeper support" tristate "IXP4XX Beeper support"
depends on ARCH_IXP4XX depends on ARCH_IXP4XX
......
...@@ -9,5 +9,6 @@ obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o ...@@ -9,5 +9,6 @@ obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
/*
* atlas_btns.c - Atlas Wallmount Touchscreen ACPI Extras
*
* Copyright (C) 2006 Jaya Kumar
* Based on Toshiba ACPI by John Belmonte and ASUS ACPI
* This work was sponsored by CIS(M) Sdn Bhd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#include <acpi/acpi_drivers.h>
#define ACPI_ATLAS_NAME "Atlas ACPI"
#define ACPI_ATLAS_CLASS "Atlas"
#define ACPI_ATLAS_BUTTON_HID "ASIM0000"
static struct input_dev *input_dev;
/* button handling code */
static acpi_status acpi_atlas_button_setup(acpi_handle region_handle,
u32 function, void *handler_context, void **return_context)
{
*return_context =
(function != ACPI_REGION_DEACTIVATE) ? handler_context : NULL;
return AE_OK;
}
static acpi_status acpi_atlas_button_handler(u32 function,
acpi_physical_address address,
u32 bit_width, acpi_integer *value,
void *handler_context, void *region_context)
{
acpi_status status;
int keycode;
if (function == ACPI_WRITE) {
keycode = KEY_F1 + (address & 0x0F);
input_report_key(input_dev, keycode, !(address & 0x10));
input_sync(input_dev);
status = 0;
} else {
printk(KERN_WARNING "atlas: shrugged on unexpected function"
":function=%x,address=%lx,value=%x\n",
function, (unsigned long)address, (u32)*value);
status = -EINVAL;
}
return status;
}
static int atlas_acpi_button_add(struct acpi_device *device)
{
acpi_status status;
int err;
input_dev = input_allocate_device();
if (!input_dev) {
printk(KERN_ERR "atlas: unable to allocate input device\n");
return -ENOMEM;
}
input_dev->name = "Atlas ACPI button driver";
input_dev->phys = "ASIM0000/atlas/input0";
input_dev->id.bustype = BUS_HOST;
input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY);
set_bit(KEY_F1, input_dev->keybit);
set_bit(KEY_F2, input_dev->keybit);
set_bit(KEY_F3, input_dev->keybit);
set_bit(KEY_F4, input_dev->keybit);
set_bit(KEY_F5, input_dev->keybit);
set_bit(KEY_F6, input_dev->keybit);
set_bit(KEY_F7, input_dev->keybit);
set_bit(KEY_F8, input_dev->keybit);
set_bit(KEY_F9, input_dev->keybit);
err = input_register_device(input_dev);
if (err) {
printk(KERN_ERR "atlas: couldn't register input device\n");
input_free_device(input_dev);
return err;
}
/* hookup button handler */
status = acpi_install_address_space_handler(device->handle,
0x81, &acpi_atlas_button_handler,
&acpi_atlas_button_setup, device);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR "Atlas: Error installing addr spc handler\n");
input_unregister_device(input_dev);
status = -EINVAL;
}
return status;
}
static int atlas_acpi_button_remove(struct acpi_device *device, int type)
{
acpi_status status;
status = acpi_remove_address_space_handler(device->handle,
0x81, &acpi_atlas_button_handler);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR "Atlas: Error removing addr spc handler\n");
status = -EINVAL;
}
input_unregister_device(input_dev);
return status;
}
static struct acpi_driver atlas_acpi_driver = {
.name = ACPI_ATLAS_NAME,
.class = ACPI_ATLAS_CLASS,
.ids = ACPI_ATLAS_BUTTON_HID,
.ops = {
.add = atlas_acpi_button_add,
.remove = atlas_acpi_button_remove,
},
};
static int __init atlas_acpi_init(void)
{
int result;
if (acpi_disabled)
return -ENODEV;
result = acpi_bus_register_driver(&atlas_acpi_driver);
if (result < 0) {
printk(KERN_ERR "Atlas ACPI: Unable to register driver\n");
return -ENODEV;
}
return 0;
}
static void __exit atlas_acpi_exit(void)
{
acpi_bus_unregister_driver(&atlas_acpi_driver);
}
module_init(atlas_acpi_init);
module_exit(atlas_acpi_exit);
MODULE_AUTHOR("Jaya Kumar");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Atlas button driver");
...@@ -335,6 +335,17 @@ static struct key_entry keymap_aopen_1559as[] = { ...@@ -335,6 +335,17 @@ static struct key_entry keymap_aopen_1559as[] = {
{ KE_END, 0 }, { KE_END, 0 },
}; };
static struct key_entry keymap_fs_amilo_d88x0[] = {
{ KE_KEY, 0x01, KEY_HELP },
{ KE_KEY, 0x08, KEY_MUTE },
{ KE_KEY, 0x31, KEY_MAIL },
{ KE_KEY, 0x36, KEY_WWW },
{ KE_KEY, 0x11, KEY_PROG1 },
{ KE_KEY, 0x12, KEY_PROG2 },
{ KE_KEY, 0x13, KEY_PROG3 },
{ KE_END, 0 }
};
/* /*
* If your machine is not here (which is currently rather likely), please send * If your machine is not here (which is currently rather likely), please send
* a list of buttons and their key codes (reported when loading this module * a list of buttons and their key codes (reported when loading this module
...@@ -413,6 +424,15 @@ static struct dmi_system_id dmi_ids[] __initdata = { ...@@ -413,6 +424,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {
}, },
.driver_data = keymap_wistron_ms2111 .driver_data = keymap_wistron_ms2111
}, },
{
.callback = dmi_matched,
.ident = "Fujitsu Siemens Amilo D88x0",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"),
},
.driver_data = keymap_fs_amilo_d88x0
},
{ NULL, } { NULL, }
}; };
......
...@@ -61,7 +61,7 @@ MODULE_LICENSE("GPL"); ...@@ -61,7 +61,7 @@ MODULE_LICENSE("GPL");
#define INPORT_REG_MODE 0x07 #define INPORT_REG_MODE 0x07
#define INPORT_RESET 0x80 #define INPORT_RESET 0x80
#ifdef CONFIG_INPUT_ATIXL #ifdef CONFIG_MOUSE_ATIXL
#define INPORT_NAME "ATI XL Mouse" #define INPORT_NAME "ATI XL Mouse"
#define INPORT_VENDOR 0x0002 #define INPORT_VENDOR 0x0002
#define INPORT_SPEED_30HZ 0x01 #define INPORT_SPEED_30HZ 0x01
......
...@@ -113,7 +113,7 @@ static int __init pc110pad_init(void) ...@@ -113,7 +113,7 @@ static int __init pc110pad_init(void)
dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
if (dev) { if (dev) {
pci_dev_put(dev); pci_dev_put(dev);
return -ENOENT; return -ENODEV;
} }
if (!request_region(pc110pad_io, 4, "pc110pad")) { if (!request_region(pc110pad_io, 4, "pc110pad")) {
......
...@@ -371,7 +371,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) ...@@ -371,7 +371,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
if (unlikely(i8042_suppress_kbd_ack)) if (unlikely(i8042_suppress_kbd_ack))
if (port_no == I8042_KBD_PORT_NO && if (port_no == I8042_KBD_PORT_NO &&
(data == 0xfa || data == 0xfe)) { (data == 0xfa || data == 0xfe)) {
i8042_suppress_kbd_ack = 0; i8042_suppress_kbd_ack--;
goto out; goto out;
} }
...@@ -543,6 +543,7 @@ static int __devinit i8042_check_aux(void) ...@@ -543,6 +543,7 @@ static int __devinit i8042_check_aux(void)
{ {
int retval = -1; int retval = -1;
int irq_registered = 0; int irq_registered = 0;
int aux_loop_broken = 0;
unsigned long flags; unsigned long flags;
unsigned char param; unsigned char param;
...@@ -572,6 +573,8 @@ static int __devinit i8042_check_aux(void) ...@@ -572,6 +573,8 @@ static int __devinit i8042_check_aux(void)
if (i8042_command(&param, I8042_CMD_AUX_TEST) || if (i8042_command(&param, I8042_CMD_AUX_TEST) ||
(param && param != 0xfa && param != 0xff)) (param && param != 0xfa && param != 0xff))
return -1; return -1;
aux_loop_broken = 1;
} }
/* /*
...@@ -595,7 +598,7 @@ static int __devinit i8042_check_aux(void) ...@@ -595,7 +598,7 @@ static int __devinit i8042_check_aux(void)
* used it for a PCI card or somethig else. * used it for a PCI card or somethig else.
*/ */
if (i8042_noloop) { if (i8042_noloop || aux_loop_broken) {
/* /*
* Without LOOP command we can't test AUX IRQ delivery. Assume the port * Without LOOP command we can't test AUX IRQ delivery. Assume the port
* is working and hope we are right. * is working and hope we are right.
...@@ -838,13 +841,14 @@ static long i8042_panic_blink(long count) ...@@ -838,13 +841,14 @@ static long i8042_panic_blink(long count)
led ^= 0x01 | 0x04; led ^= 0x01 | 0x04;
while (i8042_read_status() & I8042_STR_IBF) while (i8042_read_status() & I8042_STR_IBF)
DELAY; DELAY;
i8042_suppress_kbd_ack = 1; dbg("%02x -> i8042 (panic blink)", 0xed);
i8042_suppress_kbd_ack = 2;
i8042_write_data(0xed); /* set leds */ i8042_write_data(0xed); /* set leds */
DELAY; DELAY;
while (i8042_read_status() & I8042_STR_IBF) while (i8042_read_status() & I8042_STR_IBF)
DELAY; DELAY;
DELAY; DELAY;
i8042_suppress_kbd_ack = 1; dbg("%02x -> i8042 (panic blink)", led);
i8042_write_data(led); i8042_write_data(led);
DELAY; DELAY;
last_blink = count; last_blink = count;
......
...@@ -12,13 +12,18 @@ menuconfig INPUT_TOUCHSCREEN ...@@ -12,13 +12,18 @@ menuconfig INPUT_TOUCHSCREEN
if INPUT_TOUCHSCREEN if INPUT_TOUCHSCREEN
config TOUCHSCREEN_ADS7846 config TOUCHSCREEN_ADS7846
tristate "ADS 7846 based touchscreens" tristate "ADS 7846/7843 based touchscreens"
depends on SPI_MASTER depends on SPI_MASTER
depends on HWMON = n || HWMON
help help
Say Y here if you have a touchscreen interface using the Say Y here if you have a touchscreen interface using the
ADS7846 controller, and your board-specific initialization ADS7846 or ADS7843 controller, and your board-specific setup
code includes that in its table of SPI devices. code includes that in its table of SPI devices.
If HWMON is selected, and the driver is told the reference voltage
on your board, you will also get hwmon interfaces for the voltage
(and on ads7846, temperature) sensors of this chip.
If unsure, say N (but it's safe to say "Y"). If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
......
此差异已折叠。
...@@ -151,6 +151,10 @@ static int tsdev_open(struct inode *inode, struct file *file) ...@@ -151,6 +151,10 @@ static int tsdev_open(struct inode *inode, struct file *file)
int i = iminor(inode) - TSDEV_MINOR_BASE; int i = iminor(inode) - TSDEV_MINOR_BASE;
struct tsdev_list *list; struct tsdev_list *list;
printk(KERN_WARNING "tsdev (compaq touchscreen emulation) is scheduled "
"for removal.\nSee Documentation/feature-removal-schedule.txt "
"for details.\n");
if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK]) if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK])
return -ENODEV; return -ENODEV;
......
...@@ -57,6 +57,7 @@ static struct hid_ff_initializer inits[] = { ...@@ -57,6 +57,7 @@ static struct hid_ff_initializer inits[] = {
{ 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */ { 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */
{ 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */ { 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */
{ 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */ { 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */
{ 0x46d, 0xca03, hid_lgff_init }, /* Logitech MOMO force wheel */
#endif #endif
#ifdef CONFIG_PANTHERLORD_FF #ifdef CONFIG_PANTHERLORD_FF
{ 0x810, 0x0001, hid_plff_init }, { 0x810, 0x0001, hid_plff_init },
......
...@@ -52,6 +52,7 @@ static const struct dev_type devices[] = { ...@@ -52,6 +52,7 @@ static const struct dev_type devices[] = {
{ 0x046d, 0xc211, ff_rumble }, { 0x046d, 0xc211, ff_rumble },
{ 0x046d, 0xc219, ff_rumble }, { 0x046d, 0xc219, ff_rumble },
{ 0x046d, 0xc283, ff_joystick }, { 0x046d, 0xc283, ff_joystick },
{ 0x046d, 0xca03, ff_joystick },
{ 0x0000, 0x0000, ff_joystick } { 0x0000, 0x0000, ff_joystick }
}; };
......
#ifndef _GPIO_KEYS_H
#define _GPIO_KEYS_H
struct gpio_keys_button {
/* Configuration parameters */
int keycode;
int gpio;
int active_low;
char *desc;
};
struct gpio_keys_platform_data {
struct gpio_keys_button *buttons;
int nbuttons;
};
#endif
...@@ -5,9 +5,17 @@ ...@@ -5,9 +5,17 @@
* *
* It's OK if the min/max values are zero. * It's OK if the min/max values are zero.
*/ */
enum ads7846_filter {
ADS7846_FILTER_OK,
ADS7846_FILTER_REPEAT,
ADS7846_FILTER_IGNORE,
};
struct ads7846_platform_data { struct ads7846_platform_data {
u16 model; /* 7843, 7845, 7846. */ u16 model; /* 7843, 7845, 7846. */
u16 vref_delay_usecs; /* 0 for external vref; etc */ u16 vref_delay_usecs; /* 0 for external vref; etc */
int keep_vref_on:1; /* set to keep vref on for differential
* measurements as well */
u16 x_plate_ohms; u16 x_plate_ohms;
u16 y_plate_ohms; u16 y_plate_ohms;
...@@ -21,5 +29,9 @@ struct ads7846_platform_data { ...@@ -21,5 +29,9 @@ struct ads7846_platform_data {
u16 debounce_rep; /* additional consecutive good readings u16 debounce_rep; /* additional consecutive good readings
* required after the first two */ * required after the first two */
int (*get_pendown_state)(void); int (*get_pendown_state)(void);
int (*filter_init) (struct ads7846_platform_data *pdata,
void **filter_data);
int (*filter) (void *filter_data, int data_idx, int *val);
void (*filter_cleanup)(void *filter_data);
}; };
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册