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: do not pass injected events back to the originating handler Input: pcf8574_keypad - fix error handling in pcf8574_kp_probe Input: acecad - fix a memory leak in usb_acecad_probe error path Input: atkbd - add 'terminal' parameter for IBM Terminal keyboards Input: i8042 - add Sony VAIOs to MUX blacklist kgdboc: reset input devices (keyboards) when exiting debugger Input: export input_reset_device() for use in KGDB Input: adp5588-keys - unify common header defines
This commit is contained in:
commit
7803c05429
|
@ -74,6 +74,7 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz)
|
||||||
* 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,
|
||||||
|
struct input_handler *src_handler,
|
||||||
unsigned int type, unsigned int code, int value)
|
unsigned int type, unsigned int code, int value)
|
||||||
{
|
{
|
||||||
struct input_handler *handler;
|
struct input_handler *handler;
|
||||||
|
@ -92,6 +93,15 @@ static void input_pass_event(struct input_dev *dev,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
handler = handle->handler;
|
handler = handle->handler;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this is the handler that injected this
|
||||||
|
* particular event we want to skip it to avoid
|
||||||
|
* filters firing again and again.
|
||||||
|
*/
|
||||||
|
if (handler == src_handler)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!handler->filter) {
|
if (!handler->filter) {
|
||||||
if (filtered)
|
if (filtered)
|
||||||
break;
|
break;
|
||||||
|
@ -121,7 +131,7 @@ static void input_repeat_key(unsigned long data)
|
||||||
if (test_bit(dev->repeat_key, dev->key) &&
|
if (test_bit(dev->repeat_key, dev->key) &&
|
||||||
is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) {
|
is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) {
|
||||||
|
|
||||||
input_pass_event(dev, EV_KEY, dev->repeat_key, 2);
|
input_pass_event(dev, NULL, EV_KEY, dev->repeat_key, 2);
|
||||||
|
|
||||||
if (dev->sync) {
|
if (dev->sync) {
|
||||||
/*
|
/*
|
||||||
|
@ -130,7 +140,7 @@ static void input_repeat_key(unsigned long data)
|
||||||
* Otherwise assume that the driver will send
|
* Otherwise assume that the driver will send
|
||||||
* SYN_REPORT once it's done.
|
* SYN_REPORT once it's done.
|
||||||
*/
|
*/
|
||||||
input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
|
input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->rep[REP_PERIOD])
|
if (dev->rep[REP_PERIOD])
|
||||||
|
@ -163,6 +173,7 @@ static void input_stop_autorepeat(struct input_dev *dev)
|
||||||
#define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)
|
#define INPUT_PASS_TO_ALL (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)
|
||||||
|
|
||||||
static int input_handle_abs_event(struct input_dev *dev,
|
static int input_handle_abs_event(struct input_dev *dev,
|
||||||
|
struct input_handler *src_handler,
|
||||||
unsigned int code, int *pval)
|
unsigned int code, int *pval)
|
||||||
{
|
{
|
||||||
bool is_mt_event;
|
bool is_mt_event;
|
||||||
|
@ -206,13 +217,15 @@ static int input_handle_abs_event(struct input_dev *dev,
|
||||||
/* Flush pending "slot" event */
|
/* Flush pending "slot" event */
|
||||||
if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
|
if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
|
||||||
input_abs_set_val(dev, ABS_MT_SLOT, dev->slot);
|
input_abs_set_val(dev, ABS_MT_SLOT, dev->slot);
|
||||||
input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);
|
input_pass_event(dev, src_handler,
|
||||||
|
EV_ABS, ABS_MT_SLOT, dev->slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
return INPUT_PASS_TO_HANDLERS;
|
return INPUT_PASS_TO_HANDLERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void input_handle_event(struct input_dev *dev,
|
static void input_handle_event(struct input_dev *dev,
|
||||||
|
struct input_handler *src_handler,
|
||||||
unsigned int type, unsigned int code, int value)
|
unsigned int type, unsigned int code, int value)
|
||||||
{
|
{
|
||||||
int disposition = INPUT_IGNORE_EVENT;
|
int disposition = INPUT_IGNORE_EVENT;
|
||||||
|
@ -265,7 +278,8 @@ static void input_handle_event(struct input_dev *dev,
|
||||||
|
|
||||||
case EV_ABS:
|
case EV_ABS:
|
||||||
if (is_event_supported(code, dev->absbit, ABS_MAX))
|
if (is_event_supported(code, dev->absbit, ABS_MAX))
|
||||||
disposition = input_handle_abs_event(dev, code, &value);
|
disposition = input_handle_abs_event(dev, src_handler,
|
||||||
|
code, &value);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -323,7 +337,7 @@ static void input_handle_event(struct input_dev *dev,
|
||||||
dev->event(dev, type, code, value);
|
dev->event(dev, type, code, value);
|
||||||
|
|
||||||
if (disposition & INPUT_PASS_TO_HANDLERS)
|
if (disposition & INPUT_PASS_TO_HANDLERS)
|
||||||
input_pass_event(dev, type, code, value);
|
input_pass_event(dev, src_handler, type, code, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -352,7 +366,7 @@ void input_event(struct input_dev *dev,
|
||||||
|
|
||||||
spin_lock_irqsave(&dev->event_lock, flags);
|
spin_lock_irqsave(&dev->event_lock, flags);
|
||||||
add_input_randomness(type, code, value);
|
add_input_randomness(type, code, value);
|
||||||
input_handle_event(dev, type, code, value);
|
input_handle_event(dev, NULL, type, code, value);
|
||||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -382,7 +396,8 @@ void input_inject_event(struct input_handle *handle,
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
grab = rcu_dereference(dev->grab);
|
grab = rcu_dereference(dev->grab);
|
||||||
if (!grab || grab == handle)
|
if (!grab || grab == handle)
|
||||||
input_handle_event(dev, type, code, value);
|
input_handle_event(dev, handle->handler,
|
||||||
|
type, code, value);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||||
|
@ -595,10 +610,10 @@ static void input_dev_release_keys(struct input_dev *dev)
|
||||||
for (code = 0; code <= KEY_MAX; code++) {
|
for (code = 0; code <= KEY_MAX; code++) {
|
||||||
if (is_event_supported(code, dev->keybit, KEY_MAX) &&
|
if (is_event_supported(code, dev->keybit, KEY_MAX) &&
|
||||||
__test_and_clear_bit(code, dev->key)) {
|
__test_and_clear_bit(code, dev->key)) {
|
||||||
input_pass_event(dev, EV_KEY, code, 0);
|
input_pass_event(dev, NULL, EV_KEY, code, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
|
input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -873,9 +888,9 @@ int input_set_keycode(struct input_dev *dev,
|
||||||
!is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
|
!is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
|
||||||
__test_and_clear_bit(old_keycode, dev->key)) {
|
__test_and_clear_bit(old_keycode, dev->key)) {
|
||||||
|
|
||||||
input_pass_event(dev, EV_KEY, old_keycode, 0);
|
input_pass_event(dev, NULL, EV_KEY, old_keycode, 0);
|
||||||
if (dev->sync)
|
if (dev->sync)
|
||||||
input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
|
input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -1565,8 +1580,7 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
static void input_dev_toggle(struct input_dev *dev, bool activate)
|
||||||
static void input_dev_reset(struct input_dev *dev, bool activate)
|
|
||||||
{
|
{
|
||||||
if (!dev->event)
|
if (!dev->event)
|
||||||
return;
|
return;
|
||||||
|
@ -1580,12 +1594,44 @@ static void input_dev_reset(struct input_dev *dev, bool activate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* input_reset_device() - reset/restore the state of input device
|
||||||
|
* @dev: input device whose state needs to be reset
|
||||||
|
*
|
||||||
|
* This function tries to reset the state of an opened input device and
|
||||||
|
* bring internal state and state if the hardware in sync with each other.
|
||||||
|
* We mark all keys as released, restore LED state, repeat rate, etc.
|
||||||
|
*/
|
||||||
|
void input_reset_device(struct input_dev *dev)
|
||||||
|
{
|
||||||
|
mutex_lock(&dev->mutex);
|
||||||
|
|
||||||
|
if (dev->users) {
|
||||||
|
input_dev_toggle(dev, true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keys that have been pressed at suspend time are unlikely
|
||||||
|
* to be still pressed when we resume.
|
||||||
|
*/
|
||||||
|
spin_lock_irq(&dev->event_lock);
|
||||||
|
input_dev_release_keys(dev);
|
||||||
|
spin_unlock_irq(&dev->event_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&dev->mutex);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(input_reset_device);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
static int input_dev_suspend(struct device *dev)
|
static int input_dev_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
struct input_dev *input_dev = to_input_dev(dev);
|
struct input_dev *input_dev = to_input_dev(dev);
|
||||||
|
|
||||||
mutex_lock(&input_dev->mutex);
|
mutex_lock(&input_dev->mutex);
|
||||||
input_dev_reset(input_dev, false);
|
|
||||||
|
if (input_dev->users)
|
||||||
|
input_dev_toggle(input_dev, false);
|
||||||
|
|
||||||
mutex_unlock(&input_dev->mutex);
|
mutex_unlock(&input_dev->mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1595,18 +1641,7 @@ static int input_dev_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
struct input_dev *input_dev = to_input_dev(dev);
|
struct input_dev *input_dev = to_input_dev(dev);
|
||||||
|
|
||||||
mutex_lock(&input_dev->mutex);
|
input_reset_device(input_dev);
|
||||||
input_dev_reset(input_dev, true);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Keys that have been pressed at suspend time are unlikely
|
|
||||||
* to be still pressed when we resume.
|
|
||||||
*/
|
|
||||||
spin_lock_irq(&input_dev->event_lock);
|
|
||||||
input_dev_release_keys(input_dev);
|
|
||||||
spin_unlock_irq(&input_dev->event_lock);
|
|
||||||
|
|
||||||
mutex_unlock(&input_dev->mutex);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* I2C QWERTY Keypad and IO Expander
|
* 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-2010 Analog Devices Inc.
|
||||||
* Licensed under the GPL-2 or later.
|
* Licensed under the GPL-2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -24,29 +24,6 @@
|
||||||
|
|
||||||
#include <linux/i2c/adp5588.h>
|
#include <linux/i2c/adp5588.h>
|
||||||
|
|
||||||
/* Configuration Register1 */
|
|
||||||
#define AUTO_INC (1 << 7)
|
|
||||||
#define GPIEM_CFG (1 << 6)
|
|
||||||
#define OVR_FLOW_M (1 << 5)
|
|
||||||
#define INT_CFG (1 << 4)
|
|
||||||
#define OVR_FLOW_IEN (1 << 3)
|
|
||||||
#define K_LCK_IM (1 << 2)
|
|
||||||
#define GPI_IEN (1 << 1)
|
|
||||||
#define KE_IEN (1 << 0)
|
|
||||||
|
|
||||||
/* Interrupt Status Register */
|
|
||||||
#define CMP2_INT (1 << 5)
|
|
||||||
#define CMP1_INT (1 << 4)
|
|
||||||
#define OVR_FLOW_INT (1 << 3)
|
|
||||||
#define K_LCK_INT (1 << 2)
|
|
||||||
#define GPI_INT (1 << 1)
|
|
||||||
#define KE_INT (1 << 0)
|
|
||||||
|
|
||||||
/* Key Lock and Event Counter Register */
|
|
||||||
#define K_LCK_EN (1 << 6)
|
|
||||||
#define LCK21 0x30
|
|
||||||
#define KEC 0xF
|
|
||||||
|
|
||||||
/* Key Event Register xy */
|
/* Key Event Register xy */
|
||||||
#define KEY_EV_PRESSED (1 << 7)
|
#define KEY_EV_PRESSED (1 << 7)
|
||||||
#define KEY_EV_MASK (0x7F)
|
#define KEY_EV_MASK (0x7F)
|
||||||
|
@ -55,10 +32,6 @@
|
||||||
|
|
||||||
#define KEYP_MAX_EVENT 10
|
#define KEYP_MAX_EVENT 10
|
||||||
|
|
||||||
#define MAXGPIO 18
|
|
||||||
#define ADP_BANK(offs) ((offs) >> 3)
|
|
||||||
#define ADP_BIT(offs) (1u << ((offs) & 0x7))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Early pre 4.0 Silicon required to delay readout by at least 25ms,
|
* Early pre 4.0 Silicon required to delay readout by at least 25ms,
|
||||||
* since the Event Counter Register updated 25ms after the interrupt
|
* since the Event Counter Register updated 25ms after the interrupt
|
||||||
|
@ -75,7 +48,7 @@ struct adp5588_kpad {
|
||||||
const struct adp5588_gpi_map *gpimap;
|
const struct adp5588_gpi_map *gpimap;
|
||||||
unsigned short gpimapsize;
|
unsigned short gpimapsize;
|
||||||
#ifdef CONFIG_GPIOLIB
|
#ifdef CONFIG_GPIOLIB
|
||||||
unsigned char gpiomap[MAXGPIO];
|
unsigned char gpiomap[ADP5588_MAXGPIO];
|
||||||
bool export_gpio;
|
bool export_gpio;
|
||||||
struct gpio_chip gc;
|
struct gpio_chip gc;
|
||||||
struct mutex gpio_lock; /* Protect cached dir, dat_out */
|
struct mutex gpio_lock; /* Protect cached dir, dat_out */
|
||||||
|
@ -103,8 +76,8 @@ static int adp5588_write(struct i2c_client *client, u8 reg, u8 val)
|
||||||
static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off)
|
static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off)
|
||||||
{
|
{
|
||||||
struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
|
struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
|
||||||
unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
|
unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
|
||||||
unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
|
unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
|
||||||
|
|
||||||
return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit);
|
return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit);
|
||||||
}
|
}
|
||||||
|
@ -113,8 +86,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip,
|
||||||
unsigned off, int val)
|
unsigned off, int val)
|
||||||
{
|
{
|
||||||
struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
|
struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
|
||||||
unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
|
unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
|
||||||
unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
|
unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
|
||||||
|
|
||||||
mutex_lock(&kpad->gpio_lock);
|
mutex_lock(&kpad->gpio_lock);
|
||||||
|
|
||||||
|
@ -132,8 +105,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip,
|
||||||
static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off)
|
static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off)
|
||||||
{
|
{
|
||||||
struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
|
struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
|
||||||
unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
|
unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
|
||||||
unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
|
unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&kpad->gpio_lock);
|
mutex_lock(&kpad->gpio_lock);
|
||||||
|
@ -150,8 +123,8 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip,
|
||||||
unsigned off, int val)
|
unsigned off, int val)
|
||||||
{
|
{
|
||||||
struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
|
struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
|
||||||
unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
|
unsigned int bank = ADP5588_BANK(kpad->gpiomap[off]);
|
||||||
unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
|
unsigned int bit = ADP5588_BIT(kpad->gpiomap[off]);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&kpad->gpio_lock);
|
mutex_lock(&kpad->gpio_lock);
|
||||||
|
@ -176,7 +149,7 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip,
|
||||||
static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad,
|
static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad,
|
||||||
const struct adp5588_kpad_platform_data *pdata)
|
const struct adp5588_kpad_platform_data *pdata)
|
||||||
{
|
{
|
||||||
bool pin_used[MAXGPIO];
|
bool pin_used[ADP5588_MAXGPIO];
|
||||||
int n_unused = 0;
|
int n_unused = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -191,7 +164,7 @@ static int __devinit adp5588_build_gpiomap(struct adp5588_kpad *kpad,
|
||||||
for (i = 0; i < kpad->gpimapsize; i++)
|
for (i = 0; i < kpad->gpimapsize; i++)
|
||||||
pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true;
|
pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true;
|
||||||
|
|
||||||
for (i = 0; i < MAXGPIO; i++)
|
for (i = 0; i < ADP5588_MAXGPIO; i++)
|
||||||
if (!pin_used[i])
|
if (!pin_used[i])
|
||||||
kpad->gpiomap[n_unused++] = i;
|
kpad->gpiomap[n_unused++] = i;
|
||||||
|
|
||||||
|
@ -234,7 +207,7 @@ static int __devinit adp5588_gpio_add(struct adp5588_kpad *kpad)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i <= ADP_BANK(MAXGPIO); i++) {
|
for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
|
||||||
kpad->dat_out[i] = adp5588_read(kpad->client,
|
kpad->dat_out[i] = adp5588_read(kpad->client,
|
||||||
GPIO_DAT_OUT1 + i);
|
GPIO_DAT_OUT1 + i);
|
||||||
kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i);
|
kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i);
|
||||||
|
@ -318,11 +291,11 @@ static void adp5588_work(struct work_struct *work)
|
||||||
|
|
||||||
status = adp5588_read(client, INT_STAT);
|
status = adp5588_read(client, INT_STAT);
|
||||||
|
|
||||||
if (status & OVR_FLOW_INT) /* Unlikely and should never happen */
|
if (status & ADP5588_OVR_FLOW_INT) /* Unlikely and should never happen */
|
||||||
dev_err(&client->dev, "Event Overflow Error\n");
|
dev_err(&client->dev, "Event Overflow Error\n");
|
||||||
|
|
||||||
if (status & KE_INT) {
|
if (status & ADP5588_KE_INT) {
|
||||||
ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC;
|
ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & ADP5588_KEC;
|
||||||
if (ev_cnt) {
|
if (ev_cnt) {
|
||||||
adp5588_report_events(kpad, ev_cnt);
|
adp5588_report_events(kpad, ev_cnt);
|
||||||
input_sync(kpad->input);
|
input_sync(kpad->input);
|
||||||
|
@ -360,7 +333,7 @@ static int __devinit adp5588_setup(struct i2c_client *client)
|
||||||
if (pdata->en_keylock) {
|
if (pdata->en_keylock) {
|
||||||
ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1);
|
ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1);
|
||||||
ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2);
|
ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2);
|
||||||
ret |= adp5588_write(client, KEY_LCK_EC_STAT, K_LCK_EN);
|
ret |= adp5588_write(client, KEY_LCK_EC_STAT, ADP5588_K_LCK_EN);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < KEYP_MAX_EVENT; i++)
|
for (i = 0; i < KEYP_MAX_EVENT; i++)
|
||||||
|
@ -384,7 +357,7 @@ static int __devinit adp5588_setup(struct i2c_client *client)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gpio_data) {
|
if (gpio_data) {
|
||||||
for (i = 0; i <= ADP_BANK(MAXGPIO); i++) {
|
for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
|
||||||
int pull_mask = gpio_data->pullup_dis_mask;
|
int pull_mask = gpio_data->pullup_dis_mask;
|
||||||
|
|
||||||
ret |= adp5588_write(client, GPIO_PULL1 + i,
|
ret |= adp5588_write(client, GPIO_PULL1 + i,
|
||||||
|
@ -392,11 +365,14 @@ static int __devinit adp5588_setup(struct i2c_client *client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT |
|
ret |= adp5588_write(client, INT_STAT,
|
||||||
OVR_FLOW_INT | K_LCK_INT |
|
ADP5588_CMP2_INT | ADP5588_CMP1_INT |
|
||||||
GPI_INT | KE_INT); /* Status is W1C */
|
ADP5588_OVR_FLOW_INT | ADP5588_K_LCK_INT |
|
||||||
|
ADP5588_GPI_INT | ADP5588_KE_INT); /* Status is W1C */
|
||||||
|
|
||||||
ret |= adp5588_write(client, CFG, INT_CFG | OVR_FLOW_IEN | KE_IEN);
|
ret |= adp5588_write(client, CFG, ADP5588_INT_CFG |
|
||||||
|
ADP5588_OVR_FLOW_IEN |
|
||||||
|
ADP5588_KE_IEN);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&client->dev, "Write Error\n");
|
dev_err(&client->dev, "Write Error\n");
|
||||||
|
|
|
@ -63,6 +63,10 @@ static bool atkbd_extra;
|
||||||
module_param_named(extra, atkbd_extra, bool, 0);
|
module_param_named(extra, atkbd_extra, bool, 0);
|
||||||
MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards");
|
MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards");
|
||||||
|
|
||||||
|
static bool atkbd_terminal;
|
||||||
|
module_param_named(terminal, atkbd_terminal, bool, 0);
|
||||||
|
MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scancode to keycode tables. These are just the default setting, and
|
* Scancode to keycode tables. These are just the default setting, and
|
||||||
* are loadable via a userland utility.
|
* are loadable via a userland utility.
|
||||||
|
@ -136,7 +140,8 @@ static const unsigned short atkbd_unxlate_table[128] = {
|
||||||
#define ATKBD_CMD_ENABLE 0x00f4
|
#define ATKBD_CMD_ENABLE 0x00f4
|
||||||
#define ATKBD_CMD_RESET_DIS 0x00f5 /* Reset to defaults and disable */
|
#define ATKBD_CMD_RESET_DIS 0x00f5 /* Reset to defaults and disable */
|
||||||
#define ATKBD_CMD_RESET_DEF 0x00f6 /* Reset to defaults */
|
#define ATKBD_CMD_RESET_DEF 0x00f6 /* Reset to defaults */
|
||||||
#define ATKBD_CMD_SETALL_MBR 0x00fa
|
#define ATKBD_CMD_SETALL_MB 0x00f8 /* Set all keys to give break codes */
|
||||||
|
#define ATKBD_CMD_SETALL_MBR 0x00fa /* ... and repeat */
|
||||||
#define ATKBD_CMD_RESET_BAT 0x02ff
|
#define ATKBD_CMD_RESET_BAT 0x02ff
|
||||||
#define ATKBD_CMD_RESEND 0x00fe
|
#define ATKBD_CMD_RESEND 0x00fe
|
||||||
#define ATKBD_CMD_EX_ENABLE 0x10ea
|
#define ATKBD_CMD_EX_ENABLE 0x10ea
|
||||||
|
@ -764,6 +769,11 @@ static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (atkbd_terminal) {
|
||||||
|
ps2_command(ps2dev, param, ATKBD_CMD_SETALL_MB);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
if (target_set != 3)
|
if (target_set != 3)
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
|
|
|
@ -127,14 +127,6 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2
|
||||||
idev->id.product = 0x0001;
|
idev->id.product = 0x0001;
|
||||||
idev->id.version = 0x0100;
|
idev->id.version = 0x0100;
|
||||||
|
|
||||||
input_set_drvdata(idev, lp);
|
|
||||||
|
|
||||||
ret = input_register_device(idev);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(&client->dev, "input_register_device() failed\n");
|
|
||||||
goto fail_register;
|
|
||||||
}
|
|
||||||
|
|
||||||
lp->laststate = read_state(lp);
|
lp->laststate = read_state(lp);
|
||||||
|
|
||||||
ret = request_threaded_irq(client->irq, NULL, pcf8574_kp_irq_handler,
|
ret = request_threaded_irq(client->irq, NULL, pcf8574_kp_irq_handler,
|
||||||
|
@ -142,16 +134,21 @@ static int __devinit pcf8574_kp_probe(struct i2c_client *client, const struct i2
|
||||||
DRV_NAME, lp);
|
DRV_NAME, lp);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&client->dev, "IRQ %d is not free\n", client->irq);
|
dev_err(&client->dev, "IRQ %d is not free\n", client->irq);
|
||||||
goto fail_irq;
|
goto fail_free_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = input_register_device(idev);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&client->dev, "input_register_device() failed\n");
|
||||||
|
goto fail_free_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
i2c_set_clientdata(client, lp);
|
i2c_set_clientdata(client, lp);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_irq:
|
fail_free_irq:
|
||||||
input_unregister_device(idev);
|
free_irq(client->irq, lp);
|
||||||
fail_register:
|
fail_free_device:
|
||||||
input_set_drvdata(idev, NULL);
|
|
||||||
input_free_device(idev);
|
input_free_device(idev);
|
||||||
fail_allocate:
|
fail_allocate:
|
||||||
kfree(lp);
|
kfree(lp);
|
||||||
|
|
|
@ -350,6 +350,17 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Most (all?) VAIOs do not have external PS/2 ports nor
|
||||||
|
* they implement active multiplexing properly, and
|
||||||
|
* MUX discovery usually messes up keyboard/touchpad.
|
||||||
|
*/
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
|
||||||
|
DMI_MATCH(DMI_BOARD_NAME, "VAIO"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
/* Amoi M636/A737 */
|
/* Amoi M636/A737 */
|
||||||
.matches = {
|
.matches = {
|
||||||
|
|
|
@ -229,12 +229,13 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
|
||||||
|
|
||||||
err = input_register_device(acecad->input);
|
err = input_register_device(acecad->input);
|
||||||
if (err)
|
if (err)
|
||||||
goto fail2;
|
goto fail3;
|
||||||
|
|
||||||
usb_set_intfdata(intf, acecad);
|
usb_set_intfdata(intf, acecad);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail3: usb_free_urb(acecad->irq);
|
||||||
fail2: usb_free_coherent(dev, 8, acecad->data, acecad->data_dma);
|
fail2: usb_free_coherent(dev, 8, acecad->data, acecad->data_dma);
|
||||||
fail1: input_free_device(input_dev);
|
fail1: input_free_device(input_dev);
|
||||||
kfree(acecad);
|
kfree(acecad);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <linux/tty.h>
|
#include <linux/tty.h>
|
||||||
#include <linux/console.h>
|
#include <linux/console.h>
|
||||||
#include <linux/vt_kern.h>
|
#include <linux/vt_kern.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
|
||||||
#define MAX_CONFIG_LEN 40
|
#define MAX_CONFIG_LEN 40
|
||||||
|
|
||||||
|
@ -37,6 +38,61 @@ static struct tty_driver *kgdb_tty_driver;
|
||||||
static int kgdb_tty_line;
|
static int kgdb_tty_line;
|
||||||
|
|
||||||
#ifdef CONFIG_KDB_KEYBOARD
|
#ifdef CONFIG_KDB_KEYBOARD
|
||||||
|
static int kgdboc_reset_connect(struct input_handler *handler,
|
||||||
|
struct input_dev *dev,
|
||||||
|
const struct input_device_id *id)
|
||||||
|
{
|
||||||
|
input_reset_device(dev);
|
||||||
|
|
||||||
|
/* Retrun an error - we do not want to bind, just to reset */
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void kgdboc_reset_disconnect(struct input_handle *handle)
|
||||||
|
{
|
||||||
|
/* We do not expect anyone to actually bind to us */
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct input_device_id kgdboc_reset_ids[] = {
|
||||||
|
{
|
||||||
|
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
|
||||||
|
.evbit = { BIT_MASK(EV_KEY) },
|
||||||
|
},
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct input_handler kgdboc_reset_handler = {
|
||||||
|
.connect = kgdboc_reset_connect,
|
||||||
|
.disconnect = kgdboc_reset_disconnect,
|
||||||
|
.name = "kgdboc_reset",
|
||||||
|
.id_table = kgdboc_reset_ids,
|
||||||
|
};
|
||||||
|
|
||||||
|
static DEFINE_MUTEX(kgdboc_reset_mutex);
|
||||||
|
|
||||||
|
static void kgdboc_restore_input_helper(struct work_struct *dummy)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We need to take a mutex to prevent several instances of
|
||||||
|
* this work running on different CPUs so they don't try
|
||||||
|
* to register again already registered handler.
|
||||||
|
*/
|
||||||
|
mutex_lock(&kgdboc_reset_mutex);
|
||||||
|
|
||||||
|
if (input_register_handler(&kgdboc_reset_handler) == 0)
|
||||||
|
input_unregister_handler(&kgdboc_reset_handler);
|
||||||
|
|
||||||
|
mutex_unlock(&kgdboc_reset_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper);
|
||||||
|
|
||||||
|
static void kgdboc_restore_input(void)
|
||||||
|
{
|
||||||
|
schedule_work(&kgdboc_restore_input_work);
|
||||||
|
}
|
||||||
|
|
||||||
static int kgdboc_register_kbd(char **cptr)
|
static int kgdboc_register_kbd(char **cptr)
|
||||||
{
|
{
|
||||||
if (strncmp(*cptr, "kbd", 3) == 0) {
|
if (strncmp(*cptr, "kbd", 3) == 0) {
|
||||||
|
@ -64,10 +120,12 @@ static void kgdboc_unregister_kbd(void)
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
flush_work_sync(&kgdboc_restore_input_work);
|
||||||
}
|
}
|
||||||
#else /* ! CONFIG_KDB_KEYBOARD */
|
#else /* ! CONFIG_KDB_KEYBOARD */
|
||||||
#define kgdboc_register_kbd(x) 0
|
#define kgdboc_register_kbd(x) 0
|
||||||
#define kgdboc_unregister_kbd()
|
#define kgdboc_unregister_kbd()
|
||||||
|
#define kgdboc_restore_input()
|
||||||
#endif /* ! CONFIG_KDB_KEYBOARD */
|
#endif /* ! CONFIG_KDB_KEYBOARD */
|
||||||
|
|
||||||
static int kgdboc_option_setup(char *opt)
|
static int kgdboc_option_setup(char *opt)
|
||||||
|
@ -231,6 +289,7 @@ static void kgdboc_post_exp_handler(void)
|
||||||
dbg_restore_graphics = 0;
|
dbg_restore_graphics = 0;
|
||||||
con_debug_leave();
|
con_debug_leave();
|
||||||
}
|
}
|
||||||
|
kgdboc_restore_input();
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct kgdb_io kgdboc_io_ops = {
|
static struct kgdb_io kgdboc_io_ops = {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Analog Devices ADP5588 I/O Expander and QWERTY Keypad Controller
|
* Analog Devices ADP5588 I/O Expander and QWERTY Keypad Controller
|
||||||
*
|
*
|
||||||
* Copyright 2009 Analog Devices Inc.
|
* Copyright 2009-2010 Analog Devices Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the GPL-2 or later.
|
* Licensed under the GPL-2 or later.
|
||||||
*/
|
*/
|
||||||
|
@ -77,13 +77,26 @@
|
||||||
/* Configuration Register1 */
|
/* Configuration Register1 */
|
||||||
#define ADP5588_AUTO_INC (1 << 7)
|
#define ADP5588_AUTO_INC (1 << 7)
|
||||||
#define ADP5588_GPIEM_CFG (1 << 6)
|
#define ADP5588_GPIEM_CFG (1 << 6)
|
||||||
|
#define ADP5588_OVR_FLOW_M (1 << 5)
|
||||||
#define ADP5588_INT_CFG (1 << 4)
|
#define ADP5588_INT_CFG (1 << 4)
|
||||||
|
#define ADP5588_OVR_FLOW_IEN (1 << 3)
|
||||||
|
#define ADP5588_K_LCK_IM (1 << 2)
|
||||||
#define ADP5588_GPI_IEN (1 << 1)
|
#define ADP5588_GPI_IEN (1 << 1)
|
||||||
|
#define ADP5588_KE_IEN (1 << 0)
|
||||||
|
|
||||||
/* Interrupt Status Register */
|
/* Interrupt Status Register */
|
||||||
|
#define ADP5588_CMP2_INT (1 << 5)
|
||||||
|
#define ADP5588_CMP1_INT (1 << 4)
|
||||||
|
#define ADP5588_OVR_FLOW_INT (1 << 3)
|
||||||
|
#define ADP5588_K_LCK_INT (1 << 2)
|
||||||
#define ADP5588_GPI_INT (1 << 1)
|
#define ADP5588_GPI_INT (1 << 1)
|
||||||
#define ADP5588_KE_INT (1 << 0)
|
#define ADP5588_KE_INT (1 << 0)
|
||||||
|
|
||||||
|
/* Key Lock and Event Counter Register */
|
||||||
|
#define ADP5588_K_LCK_EN (1 << 6)
|
||||||
|
#define ADP5588_LCK21 0x30
|
||||||
|
#define ADP5588_KEC 0xF
|
||||||
|
|
||||||
#define ADP5588_MAXGPIO 18
|
#define ADP5588_MAXGPIO 18
|
||||||
#define ADP5588_BANK(offs) ((offs) >> 3)
|
#define ADP5588_BANK(offs) ((offs) >> 3)
|
||||||
#define ADP5588_BIT(offs) (1u << ((offs) & 0x7))
|
#define ADP5588_BIT(offs) (1u << ((offs) & 0x7))
|
||||||
|
|
|
@ -1406,6 +1406,8 @@ static inline void input_set_drvdata(struct input_dev *dev, void *data)
|
||||||
int __must_check input_register_device(struct input_dev *);
|
int __must_check input_register_device(struct input_dev *);
|
||||||
void input_unregister_device(struct input_dev *);
|
void input_unregister_device(struct input_dev *);
|
||||||
|
|
||||||
|
void input_reset_device(struct input_dev *);
|
||||||
|
|
||||||
int __must_check input_register_handler(struct input_handler *);
|
int __must_check input_register_handler(struct input_handler *);
|
||||||
void input_unregister_handler(struct input_handler *);
|
void input_unregister_handler(struct input_handler *);
|
||||||
|
|
||||||
|
@ -1421,7 +1423,7 @@ void input_release_device(struct input_handle *);
|
||||||
int input_open_device(struct input_handle *);
|
int input_open_device(struct input_handle *);
|
||||||
void input_close_device(struct input_handle *);
|
void input_close_device(struct input_handle *);
|
||||||
|
|
||||||
int input_flush_device(struct input_handle* handle, struct file* file);
|
int input_flush_device(struct input_handle *handle, struct file *file);
|
||||||
|
|
||||||
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
|
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
|
||||||
void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value);
|
void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value);
|
||||||
|
|
Loading…
Reference in New Issue