Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 22e93edd authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* '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
parents 1cac6ec9 9b2fb2da
Loading
Loading
Loading
Loading
+41 −27
Original line number Diff line number Diff line
@@ -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 (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:
		if (copy_from_user(joydev->keypam, argp,
				   sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)))
	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;

	default:
		if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) {
			int len;
			const char *name = dev->name;
	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;

	case JSIOCGNAME(0):
		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;
		}

		len = min_t(size_t, _IOC_SIZE(cmd), strlen(name) + 1);
		return copy_to_user(argp, name, len) ? -EFAULT : len;
	}

	return -EINVAL;
}

+1 −0
Original line number Diff line number Diff line
@@ -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 }, //?
+1 −0
Original line number Diff line number Diff line
@@ -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 */
+29 −14
Original line number Diff line number Diff line
@@ -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;
+13 −4
Original line number Diff line number Diff line
@@ -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);
	else
		dev_dbg(&ucb->ts_idev->dev, "ucb1400: unexpected IE_STATUS = %#x\n", isr);
	enable_irq(ucb->irq);
	} else
		printk(KERN_ERR "ucb1400: unexpected IE_STATUS = %#x\n", isr);
}

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);
Loading