Commit eef820dc authored by Nick Dyer's avatar Nick Dyer Committed by Dmitry Torokhov
Browse files

Input: atmel_mxt_ts - handle multiple input reports in one message

parent f3889ed1
Loading
Loading
Loading
Loading
+28 −8
Original line number Diff line number Diff line
@@ -654,6 +654,12 @@ static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
	}
}

static void mxt_input_sync(struct input_dev *input_dev)
{
	input_mt_report_pointer_emulation(input_dev, false);
	input_sync(input_dev);
}

static void mxt_input_touchevent(struct mxt_data *data,
				      struct mxt_message *message, int id)
{
@@ -667,10 +673,12 @@ static void mxt_input_touchevent(struct mxt_data *data,

	x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
	y = (message->message[2] << 4) | ((message->message[3] & 0xf));

	/* Handle 10/12 bit switching */
	if (data->max_x < 1024)
		x = x >> 2;
		x >>= 2;
	if (data->max_y < 1024)
		y = y >> 2;
		y >>= 2;

	area = message->message[4];
	amplitude = message->message[5];
@@ -689,14 +697,28 @@ static void mxt_input_touchevent(struct mxt_data *data,
		x, y, area, amplitude);

	input_mt_slot(input_dev, id);
	input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
				   status & MXT_T9_DETECT);

	if (status & MXT_T9_DETECT) {
		/*
		 * Multiple bits may be set if the host is slow to read
		 * the status messages, indicating all the events that
		 * have happened.
		 */
		if (status & MXT_T9_RELEASE) {
			input_mt_report_slot_state(input_dev,
						   MT_TOOL_FINGER, 0);
			mxt_input_sync(input_dev);
		}

		/* Touch active */
		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1);
		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
		input_report_abs(input_dev, ABS_MT_PRESSURE, amplitude);
		input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area);
	} else {
		/* Touch no longer active, close out slot */
		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
	}
}

@@ -754,10 +776,8 @@ static irqreturn_t mxt_process_messages_until_invalid(struct mxt_data *data)
		}
	} while (reportid != 0xff);

	if (update_input) {
		input_mt_report_pointer_emulation(data->input_dev, false);
		input_sync(data->input_dev);
	}
	if (update_input)
		mxt_input_sync(data->input_dev);

	return IRQ_HANDLED;
}