Commit 1e0e7a6a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull input fixes from Dmitry Torokhov:
 "Two driver fixes:

   - a fix for zinitix touchscreen to properly report contacts

   - a fix for aiptek tablet driver to be more resilient to devices with
     incorrect descriptors"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: aiptek - properly check endpoint type
  Input: zinitix - do not report shadow fingers
parents 14702b3b 5600f698
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -1787,15 +1787,13 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
	input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
	input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0);

	/* Verify that a device really has an endpoint */
	if (intf->cur_altsetting->desc.bNumEndpoints < 1) {
	err = usb_find_common_endpoints(intf->cur_altsetting,
					NULL, NULL, &endpoint, NULL);
	if (err) {
		dev_err(&intf->dev,
			"interface has %d endpoints, but must have minimum 1\n",
			intf->cur_altsetting->desc.bNumEndpoints);
		err = -EINVAL;
			"interface has no int in endpoints, but must have minimum 1\n");
		goto fail3;
	}
	endpoint = &intf->cur_altsetting->endpoint[0].desc;

	/* Go set up our URB, which is called when the tablet receives
	 * input.
+35 −9
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ struct point_coord {

struct touch_event {
	__le16	status;
	u8	finger_cnt;
	u8	finger_mask;
	u8	time_stamp;
	struct point_coord point_coord[MAX_SUPPORTED_FINGER_NUM];
};
@@ -322,11 +322,32 @@ static int zinitix_send_power_on_sequence(struct bt541_ts_data *bt541)
static void zinitix_report_finger(struct bt541_ts_data *bt541, int slot,
				  const struct point_coord *p)
{
	u16 x, y;

	if (unlikely(!(p->sub_status &
		       (SUB_BIT_UP | SUB_BIT_DOWN | SUB_BIT_MOVE)))) {
		dev_dbg(&bt541->client->dev, "unknown finger event %#02x\n",
			p->sub_status);
		return;
	}

	x = le16_to_cpu(p->x);
	y = le16_to_cpu(p->y);

	input_mt_slot(bt541->input_dev, slot);
	input_mt_report_slot_state(bt541->input_dev, MT_TOOL_FINGER, true);
	touchscreen_report_pos(bt541->input_dev, &bt541->prop,
			       le16_to_cpu(p->x), le16_to_cpu(p->y), true);
	input_report_abs(bt541->input_dev, ABS_MT_TOUCH_MAJOR, p->width);
	if (input_mt_report_slot_state(bt541->input_dev, MT_TOOL_FINGER,
				       !(p->sub_status & SUB_BIT_UP))) {
		touchscreen_report_pos(bt541->input_dev,
				       &bt541->prop, x, y, true);
		input_report_abs(bt541->input_dev,
				 ABS_MT_TOUCH_MAJOR, p->width);
		dev_dbg(&bt541->client->dev, "finger %d %s (%u, %u)\n",
			slot, p->sub_status & SUB_BIT_DOWN ? "down" : "move",
			x, y);
	} else {
		dev_dbg(&bt541->client->dev, "finger %d up (%u, %u)\n",
			slot, x, y);
	}
}

static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
@@ -334,6 +355,7 @@ static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
	struct bt541_ts_data *bt541 = bt541_handler;
	struct i2c_client *client = bt541->client;
	struct touch_event touch_event;
	unsigned long finger_mask;
	int error;
	int i;

@@ -346,10 +368,14 @@ static irqreturn_t zinitix_ts_irq_handler(int irq, void *bt541_handler)
		goto out;
	}

	for (i = 0; i < MAX_SUPPORTED_FINGER_NUM; i++)
		if (touch_event.point_coord[i].sub_status & SUB_BIT_EXIST)
			zinitix_report_finger(bt541, i,
					      &touch_event.point_coord[i]);
	finger_mask = touch_event.finger_mask;
	for_each_set_bit(i, &finger_mask, MAX_SUPPORTED_FINGER_NUM) {
		const struct point_coord *p = &touch_event.point_coord[i];

		/* Only process contacts that are actually reported */
		if (p->sub_status & SUB_BIT_EXIST)
			zinitix_report_finger(bt541, i, p);
	}

	input_mt_sync_frame(bt541->input_dev);
	input_sync(bt541->input_dev);