mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-29 23:53:32 +00:00
Merge branch 'next' into for-linus
This commit is contained in:
commit
5fc0d36c00
25 changed files with 343 additions and 254 deletions
|
@ -230,7 +230,7 @@ static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
|
||||||
input_report_key(input, BTN_RIGHT, 0);
|
input_report_key(input, BTN_RIGHT, 0);
|
||||||
input_report_key(input, BTN_MIDDLE, 0);
|
input_report_key(input, BTN_MIDDLE, 0);
|
||||||
input_report_abs(input, ABS_DISTANCE,
|
input_report_abs(input, ABS_DISTANCE,
|
||||||
input->absmax[ABS_DISTANCE]);
|
input_abs_get_max(input, ABS_DISTANCE));
|
||||||
} else {
|
} else {
|
||||||
input_report_key(input, BTN_TOUCH, 0);
|
input_report_key(input, BTN_TOUCH, 0);
|
||||||
input_report_key(input, BTN_STYLUS, 0);
|
input_report_key(input, BTN_STYLUS, 0);
|
||||||
|
@ -383,38 +383,37 @@ static int wacom_probe(struct hid_device *hdev,
|
||||||
|
|
||||||
/* Basics */
|
/* Basics */
|
||||||
input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL);
|
input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL);
|
||||||
input->absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) |
|
|
||||||
BIT(ABS_PRESSURE) | BIT(ABS_DISTANCE);
|
__set_bit(REL_WHEEL, input->relbit);
|
||||||
input->relbit[0] |= BIT(REL_WHEEL);
|
|
||||||
set_bit(BTN_TOOL_PEN, input->keybit);
|
__set_bit(BTN_TOOL_PEN, input->keybit);
|
||||||
set_bit(BTN_TOUCH, input->keybit);
|
__set_bit(BTN_TOUCH, input->keybit);
|
||||||
set_bit(BTN_STYLUS, input->keybit);
|
__set_bit(BTN_STYLUS, input->keybit);
|
||||||
set_bit(BTN_STYLUS2, input->keybit);
|
__set_bit(BTN_STYLUS2, input->keybit);
|
||||||
set_bit(BTN_LEFT, input->keybit);
|
__set_bit(BTN_LEFT, input->keybit);
|
||||||
set_bit(BTN_RIGHT, input->keybit);
|
__set_bit(BTN_RIGHT, input->keybit);
|
||||||
set_bit(BTN_MIDDLE, input->keybit);
|
__set_bit(BTN_MIDDLE, input->keybit);
|
||||||
|
|
||||||
/* Pad */
|
/* Pad */
|
||||||
input->evbit[0] |= BIT(EV_MSC);
|
input->evbit[0] |= BIT(EV_MSC);
|
||||||
input->mscbit[0] |= BIT(MSC_SERIAL);
|
|
||||||
set_bit(BTN_0, input->keybit);
|
__set_bit(MSC_SERIAL, input->mscbit);
|
||||||
set_bit(BTN_1, input->keybit);
|
|
||||||
set_bit(BTN_TOOL_FINGER, input->keybit);
|
__set_bit(BTN_0, input->keybit);
|
||||||
|
__set_bit(BTN_1, input->keybit);
|
||||||
|
__set_bit(BTN_TOOL_FINGER, input->keybit);
|
||||||
|
|
||||||
/* Distance, rubber and mouse */
|
/* Distance, rubber and mouse */
|
||||||
input->absbit[0] |= BIT(ABS_DISTANCE);
|
__set_bit(BTN_TOOL_RUBBER, input->keybit);
|
||||||
set_bit(BTN_TOOL_RUBBER, input->keybit);
|
__set_bit(BTN_TOOL_MOUSE, input->keybit);
|
||||||
set_bit(BTN_TOOL_MOUSE, input->keybit);
|
|
||||||
|
|
||||||
input->absmax[ABS_PRESSURE] = 511;
|
input_set_abs_params(input, ABS_X, 0, 16704, 4, 0);
|
||||||
input->absmax[ABS_DISTANCE] = 32;
|
input_set_abs_params(input, ABS_Y, 0, 12064, 4, 0);
|
||||||
|
input_set_abs_params(input, ABS_PRESSURE, 0, 511, 0, 0);
|
||||||
input->absmax[ABS_X] = 16704;
|
input_set_abs_params(input, ABS_DISTANCE, 0, 32, 0, 0);
|
||||||
input->absmax[ABS_Y] = 12064;
|
|
||||||
input->absfuzz[ABS_X] = 4;
|
|
||||||
input->absfuzz[ABS_Y] = 4;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_free:
|
err_free:
|
||||||
kfree(wdata);
|
kfree(wdata);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -492,13 +492,15 @@ static int str_to_user(const char *str, unsigned int maxlen, void __user *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OLD_KEY_MAX 0x1ff
|
#define OLD_KEY_MAX 0x1ff
|
||||||
static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user *p, int compat_mode)
|
static int handle_eviocgbit(struct input_dev *dev,
|
||||||
|
unsigned int type, unsigned int size,
|
||||||
|
void __user *p, int compat_mode)
|
||||||
{
|
{
|
||||||
static unsigned long keymax_warn_time;
|
static unsigned long keymax_warn_time;
|
||||||
unsigned long *bits;
|
unsigned long *bits;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
switch (_IOC_NR(cmd) & EV_MAX) {
|
switch (type) {
|
||||||
|
|
||||||
case 0: bits = dev->evbit; len = EV_MAX; break;
|
case 0: bits = dev->evbit; len = EV_MAX; break;
|
||||||
case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
|
case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
|
||||||
|
@ -517,7 +519,7 @@ static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user
|
||||||
* EVIOCGBIT(EV_KEY, KEY_MAX) and not realize that 'len'
|
* EVIOCGBIT(EV_KEY, KEY_MAX) and not realize that 'len'
|
||||||
* should be in bytes, not in bits.
|
* should be in bytes, not in bits.
|
||||||
*/
|
*/
|
||||||
if ((_IOC_NR(cmd) & EV_MAX) == EV_KEY && _IOC_SIZE(cmd) == OLD_KEY_MAX) {
|
if (type == EV_KEY && size == OLD_KEY_MAX) {
|
||||||
len = OLD_KEY_MAX;
|
len = OLD_KEY_MAX;
|
||||||
if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000))
|
if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000))
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
|
@ -528,7 +530,7 @@ static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user
|
||||||
BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long));
|
BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long));
|
||||||
}
|
}
|
||||||
|
|
||||||
return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode);
|
return bits_to_user(bits, len, size, p, compat_mode);
|
||||||
}
|
}
|
||||||
#undef OLD_KEY_MAX
|
#undef OLD_KEY_MAX
|
||||||
|
|
||||||
|
@ -542,8 +544,10 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
|
||||||
struct ff_effect effect;
|
struct ff_effect effect;
|
||||||
int __user *ip = (int __user *)p;
|
int __user *ip = (int __user *)p;
|
||||||
unsigned int i, t, u, v;
|
unsigned int i, t, u, v;
|
||||||
|
unsigned int size;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
/* First we check for fixed-length commands */
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
|
||||||
case EVIOCGVERSION:
|
case EVIOCGVERSION:
|
||||||
|
@ -610,112 +614,102 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
|
||||||
return evdev_grab(evdev, client);
|
return evdev_grab(evdev, client);
|
||||||
else
|
else
|
||||||
return evdev_ungrab(evdev, client);
|
return evdev_ungrab(evdev, client);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
size = _IOC_SIZE(cmd);
|
||||||
|
|
||||||
if (_IOC_TYPE(cmd) != 'E')
|
/* Now check variable-length commands */
|
||||||
return -EINVAL;
|
#define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
|
||||||
|
|
||||||
if (_IOC_DIR(cmd) == _IOC_READ) {
|
switch (EVIOC_MASK_SIZE(cmd)) {
|
||||||
|
|
||||||
if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
|
case EVIOCGKEY(0):
|
||||||
return handle_eviocgbit(dev, cmd, p, compat_mode);
|
return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode);
|
||||||
|
|
||||||
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
|
case EVIOCGLED(0):
|
||||||
return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd),
|
return bits_to_user(dev->led, LED_MAX, size, p, compat_mode);
|
||||||
p, compat_mode);
|
|
||||||
|
|
||||||
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
|
case EVIOCGSND(0):
|
||||||
return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd),
|
return bits_to_user(dev->snd, SND_MAX, size, p, compat_mode);
|
||||||
p, compat_mode);
|
|
||||||
|
|
||||||
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
|
case EVIOCGSW(0):
|
||||||
return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd),
|
return bits_to_user(dev->sw, SW_MAX, size, p, compat_mode);
|
||||||
p, compat_mode);
|
|
||||||
|
|
||||||
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
|
case EVIOCGNAME(0):
|
||||||
return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd),
|
return str_to_user(dev->name, size, p);
|
||||||
p, compat_mode);
|
|
||||||
|
|
||||||
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0)))
|
case EVIOCGPHYS(0):
|
||||||
return str_to_user(dev->name, _IOC_SIZE(cmd), p);
|
return str_to_user(dev->phys, size, p);
|
||||||
|
|
||||||
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0)))
|
case EVIOCGUNIQ(0):
|
||||||
return str_to_user(dev->phys, _IOC_SIZE(cmd), p);
|
return str_to_user(dev->uniq, size, p);
|
||||||
|
|
||||||
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0)))
|
case EVIOC_MASK_SIZE(EVIOCSFF):
|
||||||
return str_to_user(dev->uniq, _IOC_SIZE(cmd), p);
|
if (input_ff_effect_from_user(p, size, &effect))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
|
error = input_ff_upload(dev, &effect, file);
|
||||||
|
|
||||||
t = _IOC_NR(cmd) & ABS_MAX;
|
if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
abs.value = dev->abs[t];
|
return error;
|
||||||
abs.minimum = dev->absmin[t];
|
}
|
||||||
abs.maximum = dev->absmax[t];
|
|
||||||
abs.fuzz = dev->absfuzz[t];
|
|
||||||
abs.flat = dev->absflat[t];
|
|
||||||
abs.resolution = dev->absres[t];
|
|
||||||
|
|
||||||
if (copy_to_user(p, &abs, min_t(size_t,
|
/* Multi-number variable-length handlers */
|
||||||
_IOC_SIZE(cmd),
|
if (_IOC_TYPE(cmd) != 'E')
|
||||||
sizeof(struct input_absinfo))))
|
return -EINVAL;
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
return 0;
|
if (_IOC_DIR(cmd) == _IOC_READ) {
|
||||||
}
|
|
||||||
|
|
||||||
}
|
if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
|
||||||
|
return handle_eviocgbit(dev,
|
||||||
|
_IOC_NR(cmd) & EV_MAX, size,
|
||||||
|
p, compat_mode);
|
||||||
|
|
||||||
if (_IOC_DIR(cmd) == _IOC_WRITE) {
|
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
|
||||||
|
|
||||||
if (_IOC_NR(cmd) == _IOC_NR(EVIOCSFF)) {
|
t = _IOC_NR(cmd) & ABS_MAX;
|
||||||
|
abs = dev->absinfo[t];
|
||||||
|
|
||||||
if (input_ff_effect_from_user(p, _IOC_SIZE(cmd), &effect))
|
if (copy_to_user(p, &abs, min_t(size_t,
|
||||||
return -EFAULT;
|
size, sizeof(struct input_absinfo))))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
error = input_ff_upload(dev, &effect, file);
|
return 0;
|
||||||
|
|
||||||
if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
|
|
||||||
|
|
||||||
t = _IOC_NR(cmd) & ABS_MAX;
|
|
||||||
|
|
||||||
if (copy_from_user(&abs, p, min_t(size_t,
|
|
||||||
_IOC_SIZE(cmd),
|
|
||||||
sizeof(struct input_absinfo))))
|
|
||||||
return -EFAULT;
|
|
||||||
|
|
||||||
/* We can't change number of reserved MT slots */
|
|
||||||
if (t == ABS_MT_SLOT)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Take event lock to ensure that we are not
|
|
||||||
* changing device parameters in the middle
|
|
||||||
* of event.
|
|
||||||
*/
|
|
||||||
spin_lock_irq(&dev->event_lock);
|
|
||||||
|
|
||||||
dev->abs[t] = abs.value;
|
|
||||||
dev->absmin[t] = abs.minimum;
|
|
||||||
dev->absmax[t] = abs.maximum;
|
|
||||||
dev->absfuzz[t] = abs.fuzz;
|
|
||||||
dev->absflat[t] = abs.flat;
|
|
||||||
dev->absres[t] = _IOC_SIZE(cmd) < sizeof(struct input_absinfo) ?
|
|
||||||
0 : abs.resolution;
|
|
||||||
|
|
||||||
spin_unlock_irq(&dev->event_lock);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_IOC_DIR(cmd) == _IOC_READ) {
|
||||||
|
|
||||||
|
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
|
||||||
|
|
||||||
|
t = _IOC_NR(cmd) & ABS_MAX;
|
||||||
|
|
||||||
|
if (copy_from_user(&abs, p, min_t(size_t,
|
||||||
|
size, sizeof(struct input_absinfo))))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
if (size < sizeof(struct input_absinfo))
|
||||||
|
abs.resolution = 0;
|
||||||
|
|
||||||
|
/* We can't change number of reserved MT slots */
|
||||||
|
if (t == ABS_MT_SLOT)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Take event lock to ensure that we are not
|
||||||
|
* changing device parameters in the middle
|
||||||
|
* of event.
|
||||||
|
*/
|
||||||
|
spin_lock_irq(&dev->event_lock);
|
||||||
|
dev->absinfo[t] = abs;
|
||||||
|
spin_unlock_irq(&dev->event_lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,7 +182,7 @@ static int input_handle_abs_event(struct input_dev *dev,
|
||||||
is_mt_event = code >= ABS_MT_FIRST && code <= ABS_MT_LAST;
|
is_mt_event = code >= ABS_MT_FIRST && code <= ABS_MT_LAST;
|
||||||
|
|
||||||
if (!is_mt_event) {
|
if (!is_mt_event) {
|
||||||
pold = &dev->abs[code];
|
pold = &dev->absinfo[code].value;
|
||||||
} else if (dev->mt) {
|
} else if (dev->mt) {
|
||||||
struct input_mt_slot *mtslot = &dev->mt[dev->slot];
|
struct input_mt_slot *mtslot = &dev->mt[dev->slot];
|
||||||
pold = &mtslot->abs[code - ABS_MT_FIRST];
|
pold = &mtslot->abs[code - ABS_MT_FIRST];
|
||||||
|
@ -196,7 +196,7 @@ static int input_handle_abs_event(struct input_dev *dev,
|
||||||
|
|
||||||
if (pold) {
|
if (pold) {
|
||||||
*pval = input_defuzz_abs_event(*pval, *pold,
|
*pval = input_defuzz_abs_event(*pval, *pold,
|
||||||
dev->absfuzz[code]);
|
dev->absinfo[code].fuzz);
|
||||||
if (*pold == *pval)
|
if (*pold == *pval)
|
||||||
return INPUT_IGNORE_EVENT;
|
return INPUT_IGNORE_EVENT;
|
||||||
|
|
||||||
|
@ -204,8 +204,8 @@ static int input_handle_abs_event(struct input_dev *dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush pending "slot" event */
|
/* Flush pending "slot" event */
|
||||||
if (is_mt_event && dev->slot != dev->abs[ABS_MT_SLOT]) {
|
if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
|
||||||
dev->abs[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, EV_ABS, ABS_MT_SLOT, dev->slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,6 +390,43 @@ void input_inject_event(struct input_handle *handle,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(input_inject_event);
|
EXPORT_SYMBOL(input_inject_event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* input_alloc_absinfo - allocates array of input_absinfo structs
|
||||||
|
* @dev: the input device emitting absolute events
|
||||||
|
*
|
||||||
|
* If the absinfo struct the caller asked for is already allocated, this
|
||||||
|
* functions will not do anything.
|
||||||
|
*/
|
||||||
|
void input_alloc_absinfo(struct input_dev *dev)
|
||||||
|
{
|
||||||
|
if (!dev->absinfo)
|
||||||
|
dev->absinfo = kcalloc(ABS_CNT, sizeof(struct input_absinfo),
|
||||||
|
GFP_KERNEL);
|
||||||
|
|
||||||
|
WARN(!dev->absinfo, "%s(): kcalloc() failed?\n", __func__);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(input_alloc_absinfo);
|
||||||
|
|
||||||
|
void input_set_abs_params(struct input_dev *dev, unsigned int axis,
|
||||||
|
int min, int max, int fuzz, int flat)
|
||||||
|
{
|
||||||
|
struct input_absinfo *absinfo;
|
||||||
|
|
||||||
|
input_alloc_absinfo(dev);
|
||||||
|
if (!dev->absinfo)
|
||||||
|
return;
|
||||||
|
|
||||||
|
absinfo = &dev->absinfo[axis];
|
||||||
|
absinfo->minimum = min;
|
||||||
|
absinfo->maximum = max;
|
||||||
|
absinfo->fuzz = fuzz;
|
||||||
|
absinfo->flat = flat;
|
||||||
|
|
||||||
|
dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(input_set_abs_params);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* input_grab_device - grabs device for exclusive use
|
* input_grab_device - grabs device for exclusive use
|
||||||
* @handle: input handle that wants to own the device
|
* @handle: input handle that wants to own the device
|
||||||
|
@ -1308,6 +1345,7 @@ static void input_dev_release(struct device *device)
|
||||||
|
|
||||||
input_ff_destroy(dev);
|
input_ff_destroy(dev);
|
||||||
input_mt_destroy_slots(dev);
|
input_mt_destroy_slots(dev);
|
||||||
|
kfree(dev->absinfo);
|
||||||
kfree(dev);
|
kfree(dev);
|
||||||
|
|
||||||
module_put(THIS_MODULE);
|
module_put(THIS_MODULE);
|
||||||
|
|
|
@ -530,7 +530,7 @@ static int joydev_ioctl_common(struct joydev *joydev,
|
||||||
{
|
{
|
||||||
struct input_dev *dev = joydev->handle.dev;
|
struct input_dev *dev = joydev->handle.dev;
|
||||||
size_t len;
|
size_t len;
|
||||||
int i, j;
|
int i;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
/* Process fixed-sized commands. */
|
/* Process fixed-sized commands. */
|
||||||
|
@ -562,12 +562,11 @@ static int joydev_ioctl_common(struct joydev *joydev,
|
||||||
case JSIOCSCORR:
|
case JSIOCSCORR:
|
||||||
if (copy_from_user(joydev->corr, argp,
|
if (copy_from_user(joydev->corr, argp,
|
||||||
sizeof(joydev->corr[0]) * joydev->nabs))
|
sizeof(joydev->corr[0]) * joydev->nabs))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
for (i = 0; i < joydev->nabs; i++) {
|
for (i = 0; i < joydev->nabs; i++) {
|
||||||
j = joydev->abspam[i];
|
int val = input_abs_get_val(dev, joydev->abspam[i]);
|
||||||
joydev->abs[i] = joydev_correct(dev->abs[j],
|
joydev->abs[i] = joydev_correct(val, &joydev->corr[i]);
|
||||||
&joydev->corr[i]);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -848,25 +847,27 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
|
||||||
|
|
||||||
for (i = 0; i < joydev->nabs; i++) {
|
for (i = 0; i < joydev->nabs; i++) {
|
||||||
j = joydev->abspam[i];
|
j = joydev->abspam[i];
|
||||||
if (dev->absmax[j] == dev->absmin[j]) {
|
if (input_abs_get_max(dev, j) == input_abs_get_min(dev, j)) {
|
||||||
joydev->corr[i].type = JS_CORR_NONE;
|
joydev->corr[i].type = JS_CORR_NONE;
|
||||||
joydev->abs[i] = dev->abs[j];
|
joydev->abs[i] = input_abs_get_val(dev, j);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
joydev->corr[i].type = JS_CORR_BROKEN;
|
joydev->corr[i].type = JS_CORR_BROKEN;
|
||||||
joydev->corr[i].prec = dev->absfuzz[j];
|
joydev->corr[i].prec = input_abs_get_fuzz(dev, j);
|
||||||
joydev->corr[i].coef[0] =
|
|
||||||
(dev->absmax[j] + dev->absmin[j]) / 2 - dev->absflat[j];
|
|
||||||
joydev->corr[i].coef[1] =
|
|
||||||
(dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j];
|
|
||||||
|
|
||||||
t = (dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j];
|
t = (input_abs_get_max(dev, j) + input_abs_get_min(dev, j)) / 2;
|
||||||
|
joydev->corr[i].coef[0] = t - input_abs_get_flat(dev, j);
|
||||||
|
joydev->corr[i].coef[1] = t + input_abs_get_flat(dev, j);
|
||||||
|
|
||||||
|
t = (input_abs_get_max(dev, j) - input_abs_get_min(dev, j)) / 2
|
||||||
|
- 2 * input_abs_get_flat(dev, j);
|
||||||
if (t) {
|
if (t) {
|
||||||
joydev->corr[i].coef[2] = (1 << 29) / t;
|
joydev->corr[i].coef[2] = (1 << 29) / t;
|
||||||
joydev->corr[i].coef[3] = (1 << 29) / t;
|
joydev->corr[i].coef[3] = (1 << 29) / t;
|
||||||
|
|
||||||
joydev->abs[i] = joydev_correct(dev->abs[j],
|
joydev->abs[i] =
|
||||||
joydev->corr + i);
|
joydev_correct(input_abs_get_val(dev, j),
|
||||||
|
joydev->corr + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -342,7 +342,8 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv)
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (i < 2)
|
if (i < 2)
|
||||||
input_set_abs_params(input_dev, axes[i], 48, input_dev->abs[axes[i]] * 2 - 48, 0, 8);
|
input_set_abs_params(input_dev, axes[i],
|
||||||
|
48, input_abs_get_val(input_dev, axes[i]) * 2 - 48, 0, 8);
|
||||||
else
|
else
|
||||||
input_set_abs_params(input_dev, axes[i], 2, 253, 0, 0);
|
input_set_abs_params(input_dev, axes[i], 2, 253, 0, 0);
|
||||||
input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0);
|
input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0);
|
||||||
|
|
|
@ -452,7 +452,7 @@ static void adi_init_center(struct adi *adi)
|
||||||
for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++) {
|
for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++) {
|
||||||
|
|
||||||
t = adi->abs[i];
|
t = adi->abs[i];
|
||||||
x = adi->dev->abs[t];
|
x = input_abs_get_val(adi->dev, t);
|
||||||
|
|
||||||
if (t == ABS_THROTTLE || t == ABS_RUDDER || adi->id == ADI_ID_WGPE)
|
if (t == ABS_THROTTLE || t == ABS_RUDDER || adi->id == ADI_ID_WGPE)
|
||||||
x = i < adi->axes10 ? 512 : 128;
|
x = i < adi->axes10 ? 512 : 128;
|
||||||
|
|
|
@ -139,8 +139,8 @@ static int __init amijoy_init(void)
|
||||||
amijoy_dev[i]->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
|
amijoy_dev[i]->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
|
||||||
BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
|
BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
|
||||||
for (j = 0; j < 2; j++) {
|
for (j = 0; j < 2; j++) {
|
||||||
amijoy_dev[i]->absmin[ABS_X + j] = -1;
|
XXinput_set_abs_params(amijoy_dev[i], ABS_X + j,
|
||||||
amijoy_dev[i]->absmax[ABS_X + j] = 1;
|
-1, 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = input_register_device(amijoy_dev[i]);
|
err = input_register_device(amijoy_dev[i]);
|
||||||
|
|
|
@ -318,11 +318,8 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv)
|
||||||
for (i = 0; i < gf2k_axes[gf2k->id]; i++)
|
for (i = 0; i < gf2k_axes[gf2k->id]; i++)
|
||||||
set_bit(gf2k_abs[i], input_dev->absbit);
|
set_bit(gf2k_abs[i], input_dev->absbit);
|
||||||
|
|
||||||
for (i = 0; i < gf2k_hats[gf2k->id]; i++) {
|
for (i = 0; i < gf2k_hats[gf2k->id]; i++)
|
||||||
set_bit(ABS_HAT0X + i, input_dev->absbit);
|
input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0);
|
||||||
input_dev->absmin[ABS_HAT0X + i] = -1;
|
|
||||||
input_dev->absmax[ABS_HAT0X + i] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < gf2k_joys[gf2k->id]; i++)
|
for (i = 0; i < gf2k_joys[gf2k->id]; i++)
|
||||||
set_bit(gf2k_btn_joy[i], input_dev->keybit);
|
set_bit(gf2k_btn_joy[i], input_dev->keybit);
|
||||||
|
@ -334,11 +331,14 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv)
|
||||||
gf2k_read(gf2k, data);
|
gf2k_read(gf2k, data);
|
||||||
|
|
||||||
for (i = 0; i < gf2k_axes[gf2k->id]; i++) {
|
for (i = 0; i < gf2k_axes[gf2k->id]; i++) {
|
||||||
input_dev->absmax[gf2k_abs[i]] = (i < 2) ? input_dev->abs[gf2k_abs[i]] * 2 - 32 :
|
int max = i < 2 ?
|
||||||
input_dev->abs[gf2k_abs[0]] + input_dev->abs[gf2k_abs[1]] - 32;
|
input_abs_get_val(input_dev, gf2k_abs[i]) * 2 :
|
||||||
input_dev->absmin[gf2k_abs[i]] = 32;
|
input_abs_get_val(input_dev, gf2k_abs[0]) +
|
||||||
input_dev->absfuzz[gf2k_abs[i]] = 8;
|
input_abs_get_val(input_dev, gf2k_abs[1]);
|
||||||
input_dev->absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0;
|
int flat = i < 2 ? 24 : 0;
|
||||||
|
|
||||||
|
input_set_abs_params(input_dev, gf2k_abs[i],
|
||||||
|
32, max - 32, 8, flat);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = input_register_device(gf2k->dev);
|
err = input_register_device(gf2k->dev);
|
||||||
|
|
|
@ -270,18 +270,14 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d
|
||||||
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
|
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
|
||||||
|
|
||||||
for (i = 0; (t = interact_type[interact->type].abs[i]) >= 0; i++) {
|
for (i = 0; (t = interact_type[interact->type].abs[i]) >= 0; i++) {
|
||||||
set_bit(t, input_dev->absbit);
|
if (i < interact_type[interact->type].b8)
|
||||||
if (i < interact_type[interact->type].b8) {
|
input_set_abs_params(input_dev, t, 0, 255, 0, 0);
|
||||||
input_dev->absmin[t] = 0;
|
else
|
||||||
input_dev->absmax[t] = 255;
|
input_set_abs_params(input_dev, t, -1, 1, 0, 0);
|
||||||
} else {
|
|
||||||
input_dev->absmin[t] = -1;
|
|
||||||
input_dev->absmax[t] = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; (t = interact_type[interact->type].btn[i]) >= 0; i++)
|
for (i = 0; (t = interact_type[interact->type].btn[i]) >= 0; i++)
|
||||||
set_bit(t, input_dev->keybit);
|
__set_bit(t, input_dev->keybit);
|
||||||
|
|
||||||
err = input_register_device(interact->dev);
|
err = input_register_device(interact->dev);
|
||||||
if (err)
|
if (err)
|
||||||
|
|
|
@ -761,17 +761,21 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
|
||||||
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
|
input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
|
||||||
|
|
||||||
for (j = 0; (bits = sw_bit[sw->type][j]); j++) {
|
for (j = 0; (bits = sw_bit[sw->type][j]); j++) {
|
||||||
|
int min, max, fuzz, flat;
|
||||||
|
|
||||||
code = sw_abs[sw->type][j];
|
code = sw_abs[sw->type][j];
|
||||||
set_bit(code, input_dev->absbit);
|
min = bits == 1 ? -1 : 0;
|
||||||
input_dev->absmax[code] = (1 << bits) - 1;
|
max = (1 << bits) - 1;
|
||||||
input_dev->absmin[code] = (bits == 1) ? -1 : 0;
|
fuzz = (bits >> 1) >= 2 ? 1 << ((bits >> 1) - 2) : 0;
|
||||||
input_dev->absfuzz[code] = ((bits >> 1) >= 2) ? (1 << ((bits >> 1) - 2)) : 0;
|
flat = code == ABS_THROTTLE || bits < 5 ?
|
||||||
if (code != ABS_THROTTLE)
|
0 : 1 << (bits - 5);
|
||||||
input_dev->absflat[code] = (bits >= 5) ? (1 << (bits - 5)) : 0;
|
|
||||||
|
input_set_abs_params(input_dev, code,
|
||||||
|
min, max, fuzz, flat);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; (code = sw_btn[sw->type][j]); j++)
|
for (j = 0; (code = sw_btn[sw->type][j]); j++)
|
||||||
set_bit(code, input_dev->keybit);
|
__set_bit(code, input_dev->keybit);
|
||||||
|
|
||||||
dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k);
|
dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k);
|
||||||
|
|
||||||
|
|
|
@ -148,6 +148,7 @@ static const struct xpad_device {
|
||||||
{ 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX },
|
{ 0x0e6f, 0x0005, "Eclipse wireless Controller", 0, XTYPE_XBOX },
|
||||||
{ 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX },
|
{ 0x0e6f, 0x0006, "Edge wireless Controller", 0, XTYPE_XBOX },
|
||||||
{ 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
|
{ 0x0e6f, 0x0006, "Pelican 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
|
||||||
|
{ 0x0e6f, 0x0201, "Pelican PL-3601 'TSZ' Wired Xbox 360 Controller", 0, XTYPE_XBOX360 },
|
||||||
{ 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX },
|
{ 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", 0, XTYPE_XBOX },
|
||||||
{ 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX },
|
{ 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX },
|
||||||
{ 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX },
|
{ 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX },
|
||||||
|
|
|
@ -39,6 +39,8 @@ struct gpio_keys_drvdata {
|
||||||
struct input_dev *input;
|
struct input_dev *input;
|
||||||
struct mutex disable_lock;
|
struct mutex disable_lock;
|
||||||
unsigned int n_buttons;
|
unsigned int n_buttons;
|
||||||
|
int (*enable)(struct device *dev);
|
||||||
|
void (*disable)(struct device *dev);
|
||||||
struct gpio_button_data data[0];
|
struct gpio_button_data data[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -423,6 +425,21 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev,
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int gpio_keys_open(struct input_dev *input)
|
||||||
|
{
|
||||||
|
struct gpio_keys_drvdata *ddata = input_get_drvdata(input);
|
||||||
|
|
||||||
|
return ddata->enable ? ddata->enable(input->dev.parent) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gpio_keys_close(struct input_dev *input)
|
||||||
|
{
|
||||||
|
struct gpio_keys_drvdata *ddata = input_get_drvdata(input);
|
||||||
|
|
||||||
|
if (ddata->disable)
|
||||||
|
ddata->disable(input->dev.parent);
|
||||||
|
}
|
||||||
|
|
||||||
static int __devinit gpio_keys_probe(struct platform_device *pdev)
|
static int __devinit gpio_keys_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
|
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
|
||||||
|
@ -444,13 +461,18 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
ddata->input = input;
|
ddata->input = input;
|
||||||
ddata->n_buttons = pdata->nbuttons;
|
ddata->n_buttons = pdata->nbuttons;
|
||||||
|
ddata->enable = pdata->enable;
|
||||||
|
ddata->disable = pdata->disable;
|
||||||
mutex_init(&ddata->disable_lock);
|
mutex_init(&ddata->disable_lock);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, ddata);
|
platform_set_drvdata(pdev, ddata);
|
||||||
|
input_set_drvdata(input, ddata);
|
||||||
|
|
||||||
input->name = pdev->name;
|
input->name = pdev->name;
|
||||||
input->phys = "gpio-keys/input0";
|
input->phys = "gpio-keys/input0";
|
||||||
input->dev.parent = &pdev->dev;
|
input->dev.parent = &pdev->dev;
|
||||||
|
input->open = gpio_keys_open;
|
||||||
|
input->close = gpio_keys_close;
|
||||||
|
|
||||||
input->id.bustype = BUS_HOST;
|
input->id.bustype = BUS_HOST;
|
||||||
input->id.vendor = 0x0001;
|
input->id.vendor = 0x0001;
|
||||||
|
|
|
@ -232,15 +232,16 @@ static void hil_dev_handle_ptr_events(struct hil_dev *ptr)
|
||||||
if (absdev) {
|
if (absdev) {
|
||||||
val = lo + (hi << 8);
|
val = lo + (hi << 8);
|
||||||
#ifdef TABLET_AUTOADJUST
|
#ifdef TABLET_AUTOADJUST
|
||||||
if (val < dev->absmin[ABS_X + i])
|
if (val < input_abs_min(dev, ABS_X + i))
|
||||||
dev->absmin[ABS_X + i] = val;
|
input_abs_set_min(dev, ABS_X + i, val);
|
||||||
if (val > dev->absmax[ABS_X + i])
|
if (val > input_abs_max(dev, ABS_X + i))
|
||||||
dev->absmax[ABS_X + i] = val;
|
XXinput_abs_set_max(dev, ABS_X + i, val);
|
||||||
#endif
|
#endif
|
||||||
if (i%3) val = dev->absmax[ABS_X + i] - val;
|
if (i % 3)
|
||||||
|
val = input_abs_max(dev, ABS_X + i) - val;
|
||||||
input_report_abs(dev, ABS_X + i, val);
|
input_report_abs(dev, ABS_X + i, val);
|
||||||
} else {
|
} else {
|
||||||
val = (int) (((int8_t)lo) | ((int8_t)hi << 8));
|
val = (int) (((int8_t) lo) | ((int8_t) hi << 8));
|
||||||
if (i % 3)
|
if (i % 3)
|
||||||
val *= -1;
|
val *= -1;
|
||||||
input_report_rel(dev, REL_X + i, val);
|
input_report_rel(dev, REL_X + i, val);
|
||||||
|
@ -387,9 +388,11 @@ static void hil_dev_pointer_setup(struct hil_dev *ptr)
|
||||||
|
|
||||||
#ifdef TABLET_AUTOADJUST
|
#ifdef TABLET_AUTOADJUST
|
||||||
for (i = 0; i < ABS_MAX; i++) {
|
for (i = 0; i < ABS_MAX; i++) {
|
||||||
int diff = input_dev->absmax[ABS_X + i] / 10;
|
int diff = input_abs_max(input_dev, ABS_X + i) / 10;
|
||||||
input_dev->absmin[ABS_X + i] += diff;
|
input_abs_set_min(input_dev, ABS_X + i,
|
||||||
input_dev->absmax[ABS_X + i] -= diff;
|
input_abs_min(input_dev, ABS_X + i) + diff)
|
||||||
|
XXinput_abs_set_max(input_dev, ABS_X + i,
|
||||||
|
input_abs_max(input_dev, ABS_X + i) - diff)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -724,7 +724,6 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
|
||||||
pdata = &ac->pdata;
|
pdata = &ac->pdata;
|
||||||
|
|
||||||
ac->input = input_dev;
|
ac->input = input_dev;
|
||||||
ac->disabled = true;
|
|
||||||
ac->dev = dev;
|
ac->dev = dev;
|
||||||
ac->irq = irq;
|
ac->irq = irq;
|
||||||
ac->bops = bops;
|
ac->bops = bops;
|
||||||
|
|
|
@ -304,21 +304,25 @@ static int uinput_validate_absbits(struct input_dev *dev)
|
||||||
if (!test_bit(cnt, dev->absbit))
|
if (!test_bit(cnt, dev->absbit))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((dev->absmax[cnt] <= dev->absmin[cnt])) {
|
if (input_abs_get_max(dev, cnt) <= input_abs_get_min(dev, cnt)) {
|
||||||
printk(KERN_DEBUG
|
printk(KERN_DEBUG
|
||||||
"%s: invalid abs[%02x] min:%d max:%d\n",
|
"%s: invalid abs[%02x] min:%d max:%d\n",
|
||||||
UINPUT_NAME, cnt,
|
UINPUT_NAME, cnt,
|
||||||
dev->absmin[cnt], dev->absmax[cnt]);
|
input_abs_get_min(dev, cnt),
|
||||||
|
input_abs_get_max(dev, cnt));
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->absflat[cnt] > (dev->absmax[cnt] - dev->absmin[cnt])) {
|
if (input_abs_get_flat(dev, cnt) >
|
||||||
|
input_abs_get_max(dev, cnt) - input_abs_get_min(dev, cnt)) {
|
||||||
printk(KERN_DEBUG
|
printk(KERN_DEBUG
|
||||||
"%s: absflat[%02x] out of range: %d "
|
"%s: abs_flat #%02x out of range: %d "
|
||||||
"(min:%d/max:%d)\n",
|
"(min:%d/max:%d)\n",
|
||||||
UINPUT_NAME, cnt, dev->absflat[cnt],
|
UINPUT_NAME, cnt,
|
||||||
dev->absmin[cnt], dev->absmax[cnt]);
|
input_abs_get_flat(dev, cnt),
|
||||||
|
input_abs_get_min(dev, cnt),
|
||||||
|
input_abs_get_max(dev, cnt));
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -343,7 +347,7 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
|
||||||
struct uinput_user_dev *user_dev;
|
struct uinput_user_dev *user_dev;
|
||||||
struct input_dev *dev;
|
struct input_dev *dev;
|
||||||
char *name;
|
char *name;
|
||||||
int size;
|
int i, size;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
if (count != sizeof(struct uinput_user_dev))
|
if (count != sizeof(struct uinput_user_dev))
|
||||||
|
@ -387,11 +391,12 @@ static int uinput_setup_device(struct uinput_device *udev, const char __user *bu
|
||||||
dev->id.product = user_dev->id.product;
|
dev->id.product = user_dev->id.product;
|
||||||
dev->id.version = user_dev->id.version;
|
dev->id.version = user_dev->id.version;
|
||||||
|
|
||||||
size = sizeof(int) * ABS_CNT;
|
for (i = 0; i < ABS_CNT; i++) {
|
||||||
memcpy(dev->absmax, user_dev->absmax, size);
|
input_abs_set_max(dev, i, user_dev->absmax[i]);
|
||||||
memcpy(dev->absmin, user_dev->absmin, size);
|
input_abs_set_min(dev, i, user_dev->absmin[i]);
|
||||||
memcpy(dev->absfuzz, user_dev->absfuzz, size);
|
input_abs_set_fuzz(dev, i, user_dev->absfuzz[i]);
|
||||||
memcpy(dev->absflat, user_dev->absflat, size);
|
input_abs_set_flat(dev, i, user_dev->absflat[i]);
|
||||||
|
}
|
||||||
|
|
||||||
/* check if absmin/absmax/absfuzz/absflat are filled as
|
/* check if absmin/absmax/absfuzz/absflat are filled as
|
||||||
* told in Documentation/input/input-programming.txt */
|
* told in Documentation/input/input-programming.txt */
|
||||||
|
|
|
@ -185,7 +185,6 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
|
||||||
struct elantech_data *etd = psmouse->private;
|
struct elantech_data *etd = psmouse->private;
|
||||||
unsigned char *packet = psmouse->packet;
|
unsigned char *packet = psmouse->packet;
|
||||||
int fingers;
|
int fingers;
|
||||||
static int old_fingers;
|
|
||||||
|
|
||||||
if (etd->fw_version < 0x020000) {
|
if (etd->fw_version < 0x020000) {
|
||||||
/*
|
/*
|
||||||
|
@ -203,10 +202,13 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (etd->jumpy_cursor) {
|
if (etd->jumpy_cursor) {
|
||||||
/* Discard packets that are likely to have bogus coordinates */
|
if (fingers != 1) {
|
||||||
if (fingers > old_fingers) {
|
etd->single_finger_reports = 0;
|
||||||
|
} else if (etd->single_finger_reports < 2) {
|
||||||
|
/* Discard first 2 reports of one finger, bogus */
|
||||||
|
etd->single_finger_reports++;
|
||||||
elantech_debug("discarding packet\n");
|
elantech_debug("discarding packet\n");
|
||||||
goto discard_packet_v1;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,9 +240,6 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
|
||||||
}
|
}
|
||||||
|
|
||||||
input_sync(dev);
|
input_sync(dev);
|
||||||
|
|
||||||
discard_packet_v1:
|
|
||||||
old_fingers = fingers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -258,6 +257,14 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
|
||||||
input_report_key(dev, BTN_TOUCH, fingers != 0);
|
input_report_key(dev, BTN_TOUCH, fingers != 0);
|
||||||
|
|
||||||
switch (fingers) {
|
switch (fingers) {
|
||||||
|
case 3:
|
||||||
|
/*
|
||||||
|
* Same as one finger, except report of more than 3 fingers:
|
||||||
|
* byte 3: n4 . w1 w0 . . . .
|
||||||
|
*/
|
||||||
|
if (packet[3] & 0x80)
|
||||||
|
fingers = 4;
|
||||||
|
/* pass through... */
|
||||||
case 1:
|
case 1:
|
||||||
/*
|
/*
|
||||||
* byte 1: . . . . . x10 x9 x8
|
* byte 1: . . . . . x10 x9 x8
|
||||||
|
@ -310,6 +317,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
|
||||||
input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
|
input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
|
||||||
input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
|
input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
|
||||||
input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
|
input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
|
||||||
|
input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4);
|
||||||
input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
|
input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
|
||||||
input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
|
input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
|
||||||
|
|
||||||
|
@ -467,6 +475,7 @@ static void elantech_set_input_params(struct psmouse *psmouse)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
|
||||||
input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0);
|
input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0);
|
||||||
input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0);
|
input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0);
|
||||||
input_set_abs_params(dev, ABS_HAT0X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0);
|
input_set_abs_params(dev, ABS_HAT0X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0);
|
||||||
|
@ -733,13 +742,13 @@ int elantech_init(struct psmouse *psmouse)
|
||||||
etd->capabilities = param[0];
|
etd->capabilities = param[0];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This firmware seems to suffer from misreporting coordinates when
|
* This firmware suffers from misreporting coordinates when
|
||||||
* a touch action starts causing the mouse cursor or scrolled page
|
* a touch action starts causing the mouse cursor or scrolled page
|
||||||
* to jump. Enable a workaround.
|
* to jump. Enable a workaround.
|
||||||
*/
|
*/
|
||||||
if (etd->fw_version == 0x020022) {
|
if (etd->fw_version == 0x020022 || etd->fw_version == 0x020600) {
|
||||||
pr_info("firmware version 2.0.34 detected, enabling jumpy cursor workaround\n");
|
pr_info("firmware version 2.0.34/2.6.0 detected, enabling jumpy cursor workaround\n");
|
||||||
etd->jumpy_cursor = 1;
|
etd->jumpy_cursor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elantech_set_absolute_mode(psmouse)) {
|
if (elantech_set_absolute_mode(psmouse)) {
|
||||||
|
|
|
@ -100,10 +100,11 @@ struct elantech_data {
|
||||||
unsigned char reg_26;
|
unsigned char reg_26;
|
||||||
unsigned char debug;
|
unsigned char debug;
|
||||||
unsigned char capabilities;
|
unsigned char capabilities;
|
||||||
unsigned char paritycheck;
|
bool paritycheck;
|
||||||
unsigned char jumpy_cursor;
|
bool jumpy_cursor;
|
||||||
unsigned char hw_version;
|
unsigned char hw_version;
|
||||||
unsigned int fw_version;
|
unsigned int fw_version;
|
||||||
|
unsigned int single_finger_reports;
|
||||||
unsigned char parity[256];
|
unsigned char parity[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -145,8 +145,8 @@ static int __init pc110pad_init(void)
|
||||||
pc110pad_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
|
pc110pad_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
|
||||||
pc110pad_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
|
pc110pad_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
|
||||||
|
|
||||||
pc110pad_dev->absmax[ABS_X] = 0x1ff;
|
input_abs_set_max(pc110pad_dev, ABS_X, 0x1ff);
|
||||||
pc110pad_dev->absmax[ABS_Y] = 0x0ff;
|
input_abs_set_max(pc110pad_dev, ABS_Y, 0x0ff);
|
||||||
|
|
||||||
pc110pad_dev->open = pc110pad_open;
|
pc110pad_dev->open = pc110pad_open;
|
||||||
pc110pad_dev->close = pc110pad_close;
|
pc110pad_dev->close = pc110pad_close;
|
||||||
|
|
|
@ -635,8 +635,8 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
|
||||||
__clear_bit(REL_X, dev->relbit);
|
__clear_bit(REL_X, dev->relbit);
|
||||||
__clear_bit(REL_Y, dev->relbit);
|
__clear_bit(REL_Y, dev->relbit);
|
||||||
|
|
||||||
dev->absres[ABS_X] = priv->x_res;
|
input_abs_set_res(dev, ABS_X, priv->x_res);
|
||||||
dev->absres[ABS_Y] = priv->y_res;
|
input_abs_set_res(dev, ABS_Y, priv->y_res);
|
||||||
|
|
||||||
if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
|
if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
|
||||||
/* Clickpads report only left button */
|
/* Clickpads report only left button */
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
#include <linux/major.h>
|
#include <linux/major.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
|
#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
|
||||||
#include <linux/miscdevice.h>
|
#include <linux/miscdevice.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -134,11 +135,14 @@ static void mousedev_touchpad_event(struct input_dev *dev,
|
||||||
switch (code) {
|
switch (code) {
|
||||||
|
|
||||||
case ABS_X:
|
case ABS_X:
|
||||||
|
|
||||||
fx(0) = value;
|
fx(0) = value;
|
||||||
if (mousedev->touch && mousedev->pkt_count >= 2) {
|
if (mousedev->touch && mousedev->pkt_count >= 2) {
|
||||||
size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
|
size = input_abs_get_min(dev, ABS_X) -
|
||||||
|
input_abs_get_max(dev, ABS_X);
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
size = 256 * 2;
|
size = 256 * 2;
|
||||||
|
|
||||||
tmp = ((value - fx(2)) * 256 * FRACTION_DENOM) / size;
|
tmp = ((value - fx(2)) * 256 * FRACTION_DENOM) / size;
|
||||||
tmp += mousedev->frac_dx;
|
tmp += mousedev->frac_dx;
|
||||||
mousedev->packet.dx = tmp / FRACTION_DENOM;
|
mousedev->packet.dx = tmp / FRACTION_DENOM;
|
||||||
|
@ -150,10 +154,12 @@ static void mousedev_touchpad_event(struct input_dev *dev,
|
||||||
case ABS_Y:
|
case ABS_Y:
|
||||||
fy(0) = value;
|
fy(0) = value;
|
||||||
if (mousedev->touch && mousedev->pkt_count >= 2) {
|
if (mousedev->touch && mousedev->pkt_count >= 2) {
|
||||||
/* use X size to keep the same scale */
|
/* use X size for ABS_Y to keep the same scale */
|
||||||
size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
|
size = input_abs_get_min(dev, ABS_X) -
|
||||||
|
input_abs_get_max(dev, ABS_X);
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
size = 256 * 2;
|
size = 256 * 2;
|
||||||
|
|
||||||
tmp = -((value - fy(2)) * 256 * FRACTION_DENOM) / size;
|
tmp = -((value - fy(2)) * 256 * FRACTION_DENOM) / size;
|
||||||
tmp += mousedev->frac_dy;
|
tmp += mousedev->frac_dy;
|
||||||
mousedev->packet.dy = tmp / FRACTION_DENOM;
|
mousedev->packet.dy = tmp / FRACTION_DENOM;
|
||||||
|
@ -167,33 +173,35 @@ static void mousedev_touchpad_event(struct input_dev *dev,
|
||||||
static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
|
static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
|
||||||
unsigned int code, int value)
|
unsigned int code, int value)
|
||||||
{
|
{
|
||||||
int size;
|
int min, max, size;
|
||||||
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
|
|
||||||
case ABS_X:
|
case ABS_X:
|
||||||
size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
|
min = input_abs_get_min(dev, ABS_X);
|
||||||
|
max = input_abs_get_max(dev, ABS_X);
|
||||||
|
|
||||||
|
size = max - min;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
size = xres ? : 1;
|
size = xres ? : 1;
|
||||||
if (value > dev->absmax[ABS_X])
|
|
||||||
value = dev->absmax[ABS_X];
|
clamp(value, min, max);
|
||||||
if (value < dev->absmin[ABS_X])
|
|
||||||
value = dev->absmin[ABS_X];
|
mousedev->packet.x = ((value - min) * xres) / size;
|
||||||
mousedev->packet.x =
|
|
||||||
((value - dev->absmin[ABS_X]) * xres) / size;
|
|
||||||
mousedev->packet.abs_event = 1;
|
mousedev->packet.abs_event = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ABS_Y:
|
case ABS_Y:
|
||||||
size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y];
|
min = input_abs_get_min(dev, ABS_Y);
|
||||||
|
max = input_abs_get_max(dev, ABS_Y);
|
||||||
|
|
||||||
|
size = max - min;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
size = yres ? : 1;
|
size = yres ? : 1;
|
||||||
if (value > dev->absmax[ABS_Y])
|
|
||||||
value = dev->absmax[ABS_Y];
|
clamp(value, min, max);
|
||||||
if (value < dev->absmin[ABS_Y])
|
|
||||||
value = dev->absmin[ABS_Y];
|
mousedev->packet.y = yres - ((value - min) * yres) / size;
|
||||||
mousedev->packet.y = yres -
|
|
||||||
((value - dev->absmin[ABS_Y]) * yres) / size;
|
|
||||||
mousedev->packet.abs_event = 1;
|
mousedev->packet.abs_event = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -987,20 +987,17 @@ static int aiptek_program_tablet(struct aiptek *aiptek)
|
||||||
/* Query getXextension */
|
/* Query getXextension */
|
||||||
if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0)
|
if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
aiptek->inputdev->absmin[ABS_X] = 0;
|
input_set_abs_params(aiptek->inputdev, ABS_X, 0, ret - 1, 0, 0);
|
||||||
aiptek->inputdev->absmax[ABS_X] = ret - 1;
|
|
||||||
|
|
||||||
/* Query getYextension */
|
/* Query getYextension */
|
||||||
if ((ret = aiptek_query(aiptek, 0x01, 0x01)) < 0)
|
if ((ret = aiptek_query(aiptek, 0x01, 0x01)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
aiptek->inputdev->absmin[ABS_Y] = 0;
|
input_set_abs_params(aiptek->inputdev, ABS_Y, 0, ret - 1, 0, 0);
|
||||||
aiptek->inputdev->absmax[ABS_Y] = ret - 1;
|
|
||||||
|
|
||||||
/* Query getPressureLevels */
|
/* Query getPressureLevels */
|
||||||
if ((ret = aiptek_query(aiptek, 0x08, 0x00)) < 0)
|
if ((ret = aiptek_query(aiptek, 0x08, 0x00)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
aiptek->inputdev->absmin[ABS_PRESSURE] = 0;
|
input_set_abs_params(aiptek->inputdev, ABS_PRESSURE, 0, ret - 1, 0, 0);
|
||||||
aiptek->inputdev->absmax[ABS_PRESSURE] = ret - 1;
|
|
||||||
|
|
||||||
/* Depending on whether we are in absolute or relative mode, we will
|
/* Depending on whether we are in absolute or relative mode, we will
|
||||||
* do a switchToTablet(absolute) or switchToMouse(relative) command.
|
* do a switchToTablet(absolute) or switchToMouse(relative) command.
|
||||||
|
@ -1054,8 +1051,8 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr
|
||||||
struct aiptek *aiptek = dev_get_drvdata(dev);
|
struct aiptek *aiptek = dev_get_drvdata(dev);
|
||||||
|
|
||||||
return snprintf(buf, PAGE_SIZE, "%dx%d\n",
|
return snprintf(buf, PAGE_SIZE, "%dx%d\n",
|
||||||
aiptek->inputdev->absmax[ABS_X] + 1,
|
input_abs_get_max(aiptek->inputdev, ABS_X) + 1,
|
||||||
aiptek->inputdev->absmax[ABS_Y] + 1);
|
input_abs_get_max(aiptek->inputdev, ABS_Y) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These structs define the sysfs files, param #1 is the name of the
|
/* These structs define the sysfs files, param #1 is the name of the
|
||||||
|
@ -1843,7 +1840,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||||
for (i = 0; i < ARRAY_SIZE(speeds); ++i) {
|
for (i = 0; i < ARRAY_SIZE(speeds); ++i) {
|
||||||
aiptek->curSetting.programmableDelay = speeds[i];
|
aiptek->curSetting.programmableDelay = speeds[i];
|
||||||
(void)aiptek_program_tablet(aiptek);
|
(void)aiptek_program_tablet(aiptek);
|
||||||
if (aiptek->inputdev->absmax[ABS_X] > 0) {
|
if (input_abs_get_max(aiptek->inputdev, ABS_X) > 0) {
|
||||||
dev_info(&intf->dev,
|
dev_info(&intf->dev,
|
||||||
"Aiptek using %d ms programming speed\n",
|
"Aiptek using %d ms programming speed\n",
|
||||||
aiptek->curSetting.programmableDelay);
|
aiptek->curSetting.programmableDelay);
|
||||||
|
|
|
@ -687,10 +687,10 @@ static void wacom_tpc_finger_in(struct wacom_wac *wacom, char *data, int idx)
|
||||||
* protocol.
|
* protocol.
|
||||||
*/
|
*/
|
||||||
if (wacom->last_finger != finger) {
|
if (wacom->last_finger != finger) {
|
||||||
if (x == input->abs[ABS_X])
|
if (x == input_abs_get_val(input, ABS_X))
|
||||||
x++;
|
x++;
|
||||||
|
|
||||||
if (y == input->abs[ABS_Y])
|
if (y == input_abs_get_val(input, ABS_Y))
|
||||||
y++;
|
y++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ static int cy8ctmg110_write_regs(struct cy8ctmg110 *tsc, unsigned char reg,
|
||||||
unsigned char len, unsigned char *value)
|
unsigned char len, unsigned char *value)
|
||||||
{
|
{
|
||||||
struct i2c_client *client = tsc->client;
|
struct i2c_client *client = tsc->client;
|
||||||
unsigned int ret;
|
int ret;
|
||||||
unsigned char i2c_data[6];
|
unsigned char i2c_data[6];
|
||||||
|
|
||||||
BUG_ON(len > 5);
|
BUG_ON(len > 5);
|
||||||
|
@ -86,7 +86,7 @@ static int cy8ctmg110_write_regs(struct cy8ctmg110 *tsc, unsigned char reg,
|
||||||
ret = i2c_master_send(client, i2c_data, len + 1);
|
ret = i2c_master_send(client, i2c_data, len + 1);
|
||||||
if (ret != 1) {
|
if (ret != 1) {
|
||||||
dev_err(&client->dev, "i2c write data cmd failed\n");
|
dev_err(&client->dev, "i2c write data cmd failed\n");
|
||||||
return ret;
|
return ret ? ret : -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -96,7 +96,7 @@ static int cy8ctmg110_read_regs(struct cy8ctmg110 *tsc,
|
||||||
unsigned char *data, unsigned char len, unsigned char cmd)
|
unsigned char *data, unsigned char len, unsigned char cmd)
|
||||||
{
|
{
|
||||||
struct i2c_client *client = tsc->client;
|
struct i2c_client *client = tsc->client;
|
||||||
unsigned int ret;
|
int ret;
|
||||||
struct i2c_msg msg[2] = {
|
struct i2c_msg msg[2] = {
|
||||||
/* first write slave position to i2c devices */
|
/* first write slave position to i2c devices */
|
||||||
{ client->addr, 0, 1, &cmd },
|
{ client->addr, 0, 1, &cmd },
|
||||||
|
|
|
@ -17,6 +17,8 @@ struct gpio_keys_platform_data {
|
||||||
struct gpio_keys_button *buttons;
|
struct gpio_keys_button *buttons;
|
||||||
int nbuttons;
|
int nbuttons;
|
||||||
unsigned int rep:1; /* enable input subsystem auto repeat */
|
unsigned int rep:1; /* enable input subsystem auto repeat */
|
||||||
|
int (*enable)(struct device *dev);
|
||||||
|
void (*disable)(struct device *dev);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -776,6 +776,7 @@ struct input_absinfo {
|
||||||
#define REP_DELAY 0x00
|
#define REP_DELAY 0x00
|
||||||
#define REP_PERIOD 0x01
|
#define REP_PERIOD 0x01
|
||||||
#define REP_MAX 0x01
|
#define REP_MAX 0x01
|
||||||
|
#define REP_CNT (REP_MAX+1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sounds
|
* Sounds
|
||||||
|
@ -1099,21 +1100,18 @@ struct input_mt_slot {
|
||||||
* @repeat_key: stores key code of the last key pressed; used to implement
|
* @repeat_key: stores key code of the last key pressed; used to implement
|
||||||
* software autorepeat
|
* software autorepeat
|
||||||
* @timer: timer for software autorepeat
|
* @timer: timer for software autorepeat
|
||||||
* @abs: current values for reports from absolute axes
|
|
||||||
* @rep: current values for autorepeat parameters (delay, rate)
|
* @rep: current values for autorepeat parameters (delay, rate)
|
||||||
* @mt: pointer to array of struct input_mt_slot holding current values
|
* @mt: pointer to array of struct input_mt_slot holding current values
|
||||||
* of tracked contacts
|
* of tracked contacts
|
||||||
* @mtsize: number of MT slots the device uses
|
* @mtsize: number of MT slots the device uses
|
||||||
* @slot: MT slot currently being transmitted
|
* @slot: MT slot currently being transmitted
|
||||||
|
* @absinfo: array of &struct absinfo elements holding information
|
||||||
|
* about absolute axes (current value, min, max, flat, fuzz,
|
||||||
|
* resolution)
|
||||||
* @key: reflects current state of device's keys/buttons
|
* @key: reflects current state of device's keys/buttons
|
||||||
* @led: reflects current state of device's LEDs
|
* @led: reflects current state of device's LEDs
|
||||||
* @snd: reflects current state of sound effects
|
* @snd: reflects current state of sound effects
|
||||||
* @sw: reflects current state of device's switches
|
* @sw: reflects current state of device's switches
|
||||||
* @absmax: maximum values for events coming from absolute axes
|
|
||||||
* @absmin: minimum values for events coming from absolute axes
|
|
||||||
* @absfuzz: describes noisiness for axes
|
|
||||||
* @absflat: size of the center flat position (used by joydev)
|
|
||||||
* @absres: resolution used for events coming form absolute axes
|
|
||||||
* @open: this method is called when the very first user calls
|
* @open: this method is called when the very first user calls
|
||||||
* input_open_device(). The driver must prepare the device
|
* input_open_device(). The driver must prepare the device
|
||||||
* to start generating events (start polling thread,
|
* to start generating events (start polling thread,
|
||||||
|
@ -1180,24 +1178,19 @@ struct input_dev {
|
||||||
unsigned int repeat_key;
|
unsigned int repeat_key;
|
||||||
struct timer_list timer;
|
struct timer_list timer;
|
||||||
|
|
||||||
int abs[ABS_CNT];
|
int rep[REP_CNT];
|
||||||
int rep[REP_MAX + 1];
|
|
||||||
|
|
||||||
struct input_mt_slot *mt;
|
struct input_mt_slot *mt;
|
||||||
int mtsize;
|
int mtsize;
|
||||||
int slot;
|
int slot;
|
||||||
|
|
||||||
|
struct input_absinfo *absinfo;
|
||||||
|
|
||||||
unsigned long key[BITS_TO_LONGS(KEY_CNT)];
|
unsigned long key[BITS_TO_LONGS(KEY_CNT)];
|
||||||
unsigned long led[BITS_TO_LONGS(LED_CNT)];
|
unsigned long led[BITS_TO_LONGS(LED_CNT)];
|
||||||
unsigned long snd[BITS_TO_LONGS(SND_CNT)];
|
unsigned long snd[BITS_TO_LONGS(SND_CNT)];
|
||||||
unsigned long sw[BITS_TO_LONGS(SW_CNT)];
|
unsigned long sw[BITS_TO_LONGS(SW_CNT)];
|
||||||
|
|
||||||
int absmax[ABS_CNT];
|
|
||||||
int absmin[ABS_CNT];
|
|
||||||
int absfuzz[ABS_CNT];
|
|
||||||
int absflat[ABS_CNT];
|
|
||||||
int absres[ABS_CNT];
|
|
||||||
|
|
||||||
int (*open)(struct input_dev *dev);
|
int (*open)(struct input_dev *dev);
|
||||||
void (*close)(struct input_dev *dev);
|
void (*close)(struct input_dev *dev);
|
||||||
int (*flush)(struct input_dev *dev, struct file *file);
|
int (*flush)(struct input_dev *dev, struct file *file);
|
||||||
|
@ -1459,16 +1452,32 @@ static inline void input_set_events_per_packet(struct input_dev *dev, int n_even
|
||||||
dev->hint_events_per_packet = n_events;
|
dev->hint_events_per_packet = n_events;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat)
|
void input_alloc_absinfo(struct input_dev *dev);
|
||||||
{
|
void input_set_abs_params(struct input_dev *dev, unsigned int axis,
|
||||||
dev->absmin[axis] = min;
|
int min, int max, int fuzz, int flat);
|
||||||
dev->absmax[axis] = max;
|
|
||||||
dev->absfuzz[axis] = fuzz;
|
|
||||||
dev->absflat[axis] = flat;
|
|
||||||
|
|
||||||
dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);
|
#define INPUT_GENERATE_ABS_ACCESSORS(_suffix, _item) \
|
||||||
|
static inline int input_abs_get_##_suffix(struct input_dev *dev, \
|
||||||
|
unsigned int axis) \
|
||||||
|
{ \
|
||||||
|
return dev->absinfo ? dev->absinfo[axis]._item : 0; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static inline void input_abs_set_##_suffix(struct input_dev *dev, \
|
||||||
|
unsigned int axis, int val) \
|
||||||
|
{ \
|
||||||
|
input_alloc_absinfo(dev); \
|
||||||
|
if (dev->absinfo) \
|
||||||
|
dev->absinfo[axis]._item = val; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INPUT_GENERATE_ABS_ACCESSORS(val, value)
|
||||||
|
INPUT_GENERATE_ABS_ACCESSORS(min, minimum)
|
||||||
|
INPUT_GENERATE_ABS_ACCESSORS(max, maximum)
|
||||||
|
INPUT_GENERATE_ABS_ACCESSORS(fuzz, fuzz)
|
||||||
|
INPUT_GENERATE_ABS_ACCESSORS(flat, flat)
|
||||||
|
INPUT_GENERATE_ABS_ACCESSORS(res, resolution)
|
||||||
|
|
||||||
int input_get_keycode(struct input_dev *dev,
|
int input_get_keycode(struct input_dev *dev,
|
||||||
unsigned int scancode, unsigned int *keycode);
|
unsigned int scancode, unsigned int *keycode);
|
||||||
int input_set_keycode(struct input_dev *dev,
|
int input_set_keycode(struct input_dev *dev,
|
||||||
|
|
Loading…
Reference in a new issue