提交 22e93edd 编写于 作者: 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: ucb1400_ts - enable interrupt unconditionally
  Input: ucb1400_ts - enable ADC Filter
  Input: wacom - don't use on-stack memory for report buffers
  Input: iforce - support new revision of ACT LABS Force RS
  Input: joydev - decouple axis and button map ioctls from input constants
...@@ -456,8 +456,11 @@ static int joydev_ioctl_common(struct joydev *joydev, ...@@ -456,8 +456,11 @@ static int joydev_ioctl_common(struct joydev *joydev,
unsigned int cmd, void __user *argp) unsigned int cmd, void __user *argp)
{ {
struct input_dev *dev = joydev->handle.dev; struct input_dev *dev = joydev->handle.dev;
size_t len;
int i, j; int i, j;
const char *name;
/* Process fixed-sized commands. */
switch (cmd) { switch (cmd) {
case JS_SET_CAL: case JS_SET_CAL:
...@@ -499,9 +502,22 @@ static int joydev_ioctl_common(struct joydev *joydev, ...@@ -499,9 +502,22 @@ static int joydev_ioctl_common(struct joydev *joydev,
return copy_to_user(argp, joydev->corr, return copy_to_user(argp, joydev->corr,
sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0; sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
case JSIOCSAXMAP: }
if (copy_from_user(joydev->abspam, argp,
sizeof(__u8) * (ABS_MAX + 1))) /*
* Process variable-sized commands (the axis and button map commands
* are considered variable-sized to decouple them from the values of
* ABS_MAX and KEY_MAX).
*/
switch (cmd & ~IOCSIZE_MASK) {
case (JSIOCSAXMAP & ~IOCSIZE_MASK):
len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
/*
* FIXME: we should not copy into our axis map before
* validating the data.
*/
if (copy_from_user(joydev->abspam, argp, len))
return -EFAULT; return -EFAULT;
for (i = 0; i < joydev->nabs; i++) { for (i = 0; i < joydev->nabs; i++) {
...@@ -511,13 +527,17 @@ static int joydev_ioctl_common(struct joydev *joydev, ...@@ -511,13 +527,17 @@ static int joydev_ioctl_common(struct joydev *joydev,
} }
return 0; return 0;
case JSIOCGAXMAP: case (JSIOCGAXMAP & ~IOCSIZE_MASK):
return copy_to_user(argp, joydev->abspam, len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0; return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : 0;
case JSIOCSBTNMAP: case (JSIOCSBTNMAP & ~IOCSIZE_MASK):
if (copy_from_user(joydev->keypam, argp, len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
sizeof(__u16) * (KEY_MAX - BTN_MISC + 1))) /*
* FIXME: we should not copy into our keymap before
* validating the data.
*/
if (copy_from_user(joydev->keypam, argp, len))
return -EFAULT; return -EFAULT;
for (i = 0; i < joydev->nkey; i++) { for (i = 0; i < joydev->nkey; i++) {
...@@ -529,25 +549,19 @@ static int joydev_ioctl_common(struct joydev *joydev, ...@@ -529,25 +549,19 @@ static int joydev_ioctl_common(struct joydev *joydev,
return 0; return 0;
case JSIOCGBTNMAP: case (JSIOCGBTNMAP & ~IOCSIZE_MASK):
return copy_to_user(argp, joydev->keypam, len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0; return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : 0;
default: case JSIOCGNAME(0):
if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) { name = dev->name;
int len; if (!name)
const char *name = dev->name; return 0;
if (!name) len = min_t(size_t, _IOC_SIZE(cmd), strlen(name) + 1);
return 0; return copy_to_user(argp, name, len) ? -EFAULT : len;
len = strlen(name) + 1;
if (len > _IOC_SIZE(cmd))
len = _IOC_SIZE(cmd);
if (copy_to_user(argp, name, len))
return -EFAULT;
return len;
}
} }
return -EINVAL; return -EINVAL;
} }
......
...@@ -74,6 +74,7 @@ static struct iforce_device iforce_device[] = { ...@@ -74,6 +74,7 @@ static struct iforce_device iforce_device[] = {
{ 0x05ef, 0x8884, "AVB Mag Turbo Force", btn_avb_wheel, abs_wheel, ff_iforce }, { 0x05ef, 0x8884, "AVB Mag Turbo Force", btn_avb_wheel, abs_wheel, ff_iforce },
{ 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel", btn_avb_tw, abs_wheel, ff_iforce }, //? { 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel", btn_avb_tw, abs_wheel, ff_iforce }, //?
{ 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //? { 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //?
{ 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce },
{ 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //?
{ 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //?
{ 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? { 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //?
......
...@@ -223,6 +223,7 @@ static struct usb_device_id iforce_usb_ids [] = { ...@@ -223,6 +223,7 @@ static struct usb_device_id iforce_usb_ids [] = {
{ USB_DEVICE(0x05ef, 0x8884) }, /* AVB Mag Turbo Force */ { USB_DEVICE(0x05ef, 0x8884) }, /* AVB Mag Turbo Force */
{ USB_DEVICE(0x05ef, 0x8888) }, /* AVB Top Shot FFB Racing Wheel */ { USB_DEVICE(0x05ef, 0x8888) }, /* AVB Top Shot FFB Racing Wheel */
{ USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */ { USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */
{ USB_DEVICE(0x061c, 0xc084) }, /* ACT LABS Force RS */
{ USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */ { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */
{ USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */ { USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */
{ USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */ { USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */
......
...@@ -388,6 +388,32 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi ...@@ -388,6 +388,32 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi
return result; return result;
} }
static int wacom_query_tablet_data(struct usb_interface *intf)
{
unsigned char *rep_data;
int limit = 0;
int error;
rep_data = kmalloc(2, GFP_KERNEL);
if (!rep_data)
return -ENOMEM;
do {
rep_data[0] = 2;
rep_data[1] = 2;
error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
2, rep_data, 2);
if (error >= 0)
error = usb_get_report(intf,
WAC_HID_FEATURE_REPORT, 2,
rep_data, 2);
} while ((error < 0 || rep_data[1] != 2) && limit++ < 5);
kfree(rep_data);
return error < 0 ? error : 0;
}
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
{ {
struct usb_device *dev = interface_to_usbdev(intf); struct usb_device *dev = interface_to_usbdev(intf);
...@@ -398,7 +424,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -398,7 +424,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
struct wacom_features *features; struct wacom_features *features;
struct input_dev *input_dev; struct input_dev *input_dev;
int error = -ENOMEM; int error = -ENOMEM;
char rep_data[2], limit = 0;
struct hid_descriptor *hid_desc; struct hid_descriptor *hid_desc;
wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
...@@ -489,20 +514,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -489,20 +514,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
/* /*
* Ask the tablet to report tablet data if it is not a Tablet PC. * Ask the tablet to report tablet data if it is not a Tablet PC.
* Repeat until it succeeds * Note that if query fails it is not a hard failure.
*/ */
if (wacom_wac->features->type != TABLETPC) { if (wacom_wac->features->type != TABLETPC)
do { wacom_query_tablet_data(intf);
rep_data[0] = 2;
rep_data[1] = 2;
error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
2, rep_data, 2);
if (error >= 0)
error = usb_get_report(intf,
WAC_HID_FEATURE_REPORT, 2,
rep_data, 2);
} while ((error < 0 || rep_data[1] != 2) && limit++ < 5);
}
usb_set_intfdata(intf, wacom); usb_set_intfdata(intf, wacom);
return 0; return 0;
......
...@@ -170,11 +170,11 @@ static void ucb1400_handle_pending_irq(struct ucb1400_ts *ucb) ...@@ -170,11 +170,11 @@ static void ucb1400_handle_pending_irq(struct ucb1400_ts *ucb)
ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, isr); ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, isr);
ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0); ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);
if (isr & UCB_IE_TSPX) { if (isr & UCB_IE_TSPX)
ucb1400_ts_irq_disable(ucb->ac97); ucb1400_ts_irq_disable(ucb->ac97);
enable_irq(ucb->irq); else
} else dev_dbg(&ucb->ts_idev->dev, "ucb1400: unexpected IE_STATUS = %#x\n", isr);
printk(KERN_ERR "ucb1400: unexpected IE_STATUS = %#x\n", isr); enable_irq(ucb->irq);
} }
static int ucb1400_ts_thread(void *_ucb) static int ucb1400_ts_thread(void *_ucb)
...@@ -345,6 +345,7 @@ static int ucb1400_ts_detect_irq(struct ucb1400_ts *ucb) ...@@ -345,6 +345,7 @@ static int ucb1400_ts_detect_irq(struct ucb1400_ts *ucb)
static int ucb1400_ts_probe(struct platform_device *dev) static int ucb1400_ts_probe(struct platform_device *dev)
{ {
int error, x_res, y_res; int error, x_res, y_res;
u16 fcsr;
struct ucb1400_ts *ucb = dev->dev.platform_data; struct ucb1400_ts *ucb = dev->dev.platform_data;
ucb->ts_idev = input_allocate_device(); ucb->ts_idev = input_allocate_device();
...@@ -382,6 +383,14 @@ static int ucb1400_ts_probe(struct platform_device *dev) ...@@ -382,6 +383,14 @@ static int ucb1400_ts_probe(struct platform_device *dev)
ucb->ts_idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); ucb->ts_idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
ucb->ts_idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); ucb->ts_idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
/*
* Enable ADC filter to prevent horrible jitter on Colibri.
* This also further reduces jitter on boards where ADCSYNC
* pin is connected.
*/
fcsr = ucb1400_reg_read(ucb->ac97, UCB_FCSR);
ucb1400_reg_write(ucb->ac97, UCB_FCSR, fcsr | UCB_FCSR_AVE);
ucb1400_adc_enable(ucb->ac97); ucb1400_adc_enable(ucb->ac97);
x_res = ucb1400_ts_read_xres(ucb); x_res = ucb1400_ts_read_xres(ucb);
y_res = ucb1400_ts_read_yres(ucb); y_res = ucb1400_ts_read_yres(ucb);
......
...@@ -73,6 +73,10 @@ ...@@ -73,6 +73,10 @@
#define UCB_ADC_DATA 0x68 #define UCB_ADC_DATA 0x68
#define UCB_ADC_DAT_VALID (1 << 15) #define UCB_ADC_DAT_VALID (1 << 15)
#define UCB_FCSR 0x6c
#define UCB_FCSR_AVE (1 << 12)
#define UCB_ADC_DAT_MASK 0x3ff #define UCB_ADC_DAT_MASK 0x3ff
#define UCB_ID 0x7e #define UCB_ID 0x7e
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册