提交 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,
unsigned int cmd, void __user *argp)
{
struct input_dev *dev = joydev->handle.dev;
size_t len;
int i, j;
const char *name;
/* Process fixed-sized commands. */
switch (cmd) {
case JS_SET_CAL:
......@@ -499,9 +502,22 @@ static int joydev_ioctl_common(struct joydev *joydev,
return copy_to_user(argp, joydev->corr,
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;
for (i = 0; i < joydev->nabs; i++) {
......@@ -511,13 +527,17 @@ static int joydev_ioctl_common(struct joydev *joydev,
}
return 0;
case JSIOCGAXMAP:
return copy_to_user(argp, joydev->abspam,
sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0;
case JSIOCSBTNMAP:
if (copy_from_user(joydev->keypam, argp,
sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)))
case (JSIOCGAXMAP & ~IOCSIZE_MASK):
len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : 0;
case (JSIOCSBTNMAP & ~IOCSIZE_MASK):
len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
/*
* FIXME: we should not copy into our keymap before
* validating the data.
*/
if (copy_from_user(joydev->keypam, argp, len))
return -EFAULT;
for (i = 0; i < joydev->nkey; i++) {
......@@ -529,25 +549,19 @@ static int joydev_ioctl_common(struct joydev *joydev,
return 0;
case JSIOCGBTNMAP:
return copy_to_user(argp, joydev->keypam,
sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0;
case (JSIOCGBTNMAP & ~IOCSIZE_MASK):
len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : 0;
default:
if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) {
int len;
const char *name = dev->name;
if (!name)
return 0;
len = strlen(name) + 1;
if (len > _IOC_SIZE(cmd))
len = _IOC_SIZE(cmd);
if (copy_to_user(argp, name, len))
return -EFAULT;
return len;
}
case JSIOCGNAME(0):
name = dev->name;
if (!name)
return 0;
len = min_t(size_t, _IOC_SIZE(cmd), strlen(name) + 1);
return copy_to_user(argp, name, len) ? -EFAULT : len;
}
return -EINVAL;
}
......
......@@ -74,6 +74,7 @@ static struct iforce_device iforce_device[] = {
{ 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 }, //?
{ 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, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, 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 [] = {
{ USB_DEVICE(0x05ef, 0x8884) }, /* AVB Mag Turbo Force */
{ USB_DEVICE(0x05ef, 0x8888) }, /* AVB Top Shot FFB Racing Wheel */
{ 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, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */
{ 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
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)
{
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
struct wacom_features *features;
struct input_dev *input_dev;
int error = -ENOMEM;
char rep_data[2], limit = 0;
struct hid_descriptor *hid_desc;
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
/*
* 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) {
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);
}
if (wacom_wac->features->type != TABLETPC)
wacom_query_tablet_data(intf);
usb_set_intfdata(intf, wacom);
return 0;
......
......@@ -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, 0);
if (isr & UCB_IE_TSPX) {
if (isr & UCB_IE_TSPX)
ucb1400_ts_irq_disable(ucb->ac97);
enable_irq(ucb->irq);
} else
printk(KERN_ERR "ucb1400: unexpected IE_STATUS = %#x\n", isr);
else
dev_dbg(&ucb->ts_idev->dev, "ucb1400: unexpected IE_STATUS = %#x\n", isr);
enable_irq(ucb->irq);
}
static int ucb1400_ts_thread(void *_ucb)
......@@ -345,6 +345,7 @@ static int ucb1400_ts_detect_irq(struct ucb1400_ts *ucb)
static int ucb1400_ts_probe(struct platform_device *dev)
{
int error, x_res, y_res;
u16 fcsr;
struct ucb1400_ts *ucb = dev->dev.platform_data;
ucb->ts_idev = input_allocate_device();
......@@ -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->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);
x_res = ucb1400_ts_read_xres(ucb);
y_res = ucb1400_ts_read_yres(ucb);
......
......@@ -73,6 +73,10 @@
#define UCB_ADC_DATA 0x68
#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_ID 0x7e
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册