static int mt_process_slot(struct mt_device *td, struct input_dev *input,
			    struct mt_application *app,
			    struct mt_usages *slot)
{
	struct input_mt *mt = input->mt;
	__s32 quirks = app->quirks;
	bool valid = true;
	bool confidence_state = true;
	bool inrange_state = false;
	int active;
	int slotnum;
	int tool = MT_TOOL_FINGER;

	if (!slot)
		return -EINVAL;

	if ((quirks & MT_QUIRK_CONTACT_CNT_ACCURATE) &&
	    app->num_received >= app->num_expected)
		return -EAGAIN;

	if (!(quirks & MT_QUIRK_ALWAYS_VALID)) {
		if (quirks & MT_QUIRK_VALID_IS_INRANGE)
			valid = *slot->inrange_state;
		if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
			valid = *slot->tip_state;
		if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE)
			valid = *slot->confidence_state;

		if (!valid)
			return 0;
	}

	slotnum = mt_compute_slot(td, app, slot, input);
	if (slotnum < 0 || slotnum >= td->maxcontacts)
		return 0;

	if ((quirks & MT_QUIRK_IGNORE_DUPLICATES) && mt) {
		struct input_mt_slot *i_slot = &mt->slots[slotnum];

		if (input_mt_is_active(i_slot) &&
		    input_mt_is_used(mt, i_slot))
			return -EAGAIN;
	}

	if (quirks & MT_QUIRK_CONFIDENCE)
		confidence_state = *slot->confidence_state;

	if (quirks & MT_QUIRK_HOVERING)
		inrange_state = *slot->inrange_state;

	active = *slot->tip_state || inrange_state;

	if (app->application == HID_GD_SYSTEM_MULTIAXIS)
		tool = MT_TOOL_DIAL;
	else if (unlikely(!confidence_state)) {
		tool = MT_TOOL_PALM;
		if (!active && mt &&
		    input_mt_is_active(&mt->slots[slotnum])) {
			/*
			 * The non-confidence was reported for
			 * previously valid contact that is also no
			 * longer valid. We can't simply report
			 * lift-off as userspace will not be aware
			 * of non-confidence, so we need to split
			 * it into 2 events: active MT_TOOL_PALM
			 * and a separate liftoff.
			 */
			active = true;
			set_bit(slotnum, app->pending_palm_slots);
		}
	}

	input_mt_slot(input, slotnum);
	input_mt_report_slot_state(input, tool, active);
	if (active) {
		/* this finger is in proximity of the sensor */
		int wide = (*slot->w > *slot->h);
		int major = max(*slot->w, *slot->h);
		int minor = min(*slot->w, *slot->h);
		int orientation = wide;
		int max_azimuth;
		int azimuth;

		if (slot->a != DEFAULT_ZERO) {
			/*
			 * Azimuth is counter-clockwise and ranges from [0, MAX)
			 * (a full revolution). Convert it to clockwise ranging
			 * [-MAX/2, MAX/2].
			 *
			 * Note that ABS_MT_ORIENTATION require us to report
			 * the limit of [-MAX/4, MAX/4], but the value can go
			 * out of range to [-MAX/2, MAX/2] to report an upside
			 * down ellipsis.
			 */
			azimuth = *slot->a;
			max_azimuth = input_abs_get_max(input,
							ABS_MT_ORIENTATION);
			if (azimuth > max_azimuth * 2)
				azimuth -= max_azimuth * 4;
			orientation = -azimuth;
		}

		if (quirks & MT_QUIRK_TOUCH_SIZE_SCALING) {
			/*
			 * divided by two to match visual scale of touch
			 * for devices with this quirk
			 */
			major = major >> 1;
			minor = minor >> 1;
		}

		input_event(input, EV_ABS, ABS_MT_POSITION_X, *slot->x);
		input_event(input, EV_ABS, ABS_MT_POSITION_Y, *slot->y);
		input_event(input, EV_ABS, ABS_MT_TOOL_X, *slot->cx);
		input_event(input, EV_ABS, ABS_MT_TOOL_Y, *slot->cy);
		input_event(input, EV_ABS, ABS_MT_DISTANCE, !*slot->tip_state);
		input_event(input, EV_ABS, ABS_MT_ORIENTATION, orientation);
		input_event(input, EV_ABS, ABS_MT_PRESSURE, *slot->p);
		input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
		input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);

		set_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags);
	}

	return 0;
}

#define MT_QUIRK_NOT_SEEN_MEANS_UP	BIT(0)

#define MT_QUIRK_ALWAYS_VALID		BIT(4)

#define MT_QUIRK_VALID_IS_INRANGE	BIT(5)

#define MT_QUIRK_VALID_IS_CONFIDENCE	BIT(6)

#define MT_QUIRK_CONFIDENCE		BIT(7)

#define MT_QUIRK_IGNORE_DUPLICATES	BIT(10)

#define MT_QUIRK_HOVERING		BIT(11)

#define MT_QUIRK_CONTACT_CNT_ACCURATE	BIT(12)

#define MT_QUIRK_TOUCH_SIZE_SCALING	BIT(15)

#define MT_IO_FLAGS_ACTIVE_SLOTS	1

static const bool mtrue = true;

static const bool mfalse;

static const __s32 mzero;

#define DEFAULT_ZERO	((void *)&mzero)

struct mt_usages {
	struct list_head list;
	__s32 *x, *y, *cx, *cy, *p, *w, *h, *a;
	__s32 *contactid;	/* the device ContactID assigned to this slot */
	bool *tip_state;	/* is the touch valid? */
	bool *inrange_state;	/* is the finger in proximity of the sensor? */
	bool *confidence_state;	/* is the touch made by a finger? */
}

struct mt_application {
	struct list_head list;
	unsigned int application;
	unsigned int report_id;
	struct list_head mt_usages;	/* mt usages list */

	__s32 quirks;

	__s32 *scantime;		/* scantime reported */
	__s32 scantime_logical_max;	/* max value for raw scantime */

	__s32 *raw_cc;			/* contact count in the report */
	int left_button_state;		/* left button state */
	unsigned int mt_flags;		/* flags to pass to input-mt */

	unsigned long *pending_palm_slots;	/* slots where we reported palm
						 * and need to release */

	__u8 num_received;	/* how many contacts we received */
	__u8 num_expected;	/* expected last contact index */
	__u8 buttons_count;	/* number of physical buttons per touchpad */
	__u8 touches_by_report;	/* how many touches are present in one report:
				 * 1 means we should use a serial protocol
				 * > 1 means hybrid (multitouch) protocol
				 */

	__s32 dev_time;		/* the scan time provided by the device */
	unsigned long jiffies;	/* the frame's jiffies */
	int timestamp;		/* the timestamp to be sent */
	int prev_scantime;		/* scantime reported previously */

	bool have_contact_count;
}

struct mt_class {
	__s32 name;	/* MT_CLS */
	__s32 quirks;
	__s32 sn_move;	/* Signal/noise ratio for move events */
	__s32 sn_width;	/* Signal/noise ratio for width events */
	__s32 sn_height;	/* Signal/noise ratio for height events */
	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
	__u8 maxcontacts;
	bool is_indirect;	/* true for touchpads */
	bool export_all_inputs;	/* do not ignore mouse, keyboards, etc... */
}

struct mt_report_data {
	struct list_head list;
	struct hid_report *report;
	struct mt_application *application;
	bool is_mt_collection;
}


static bool match_scancode(struct hid_usage *usage,
			   unsigned int cur_idx, unsigned int scancode)
{
	return (usage->hid & (HID_USAGE_PAGE | HID_USAGE)) == scancode;
}

HID: core: Sanitize event code and type when mapping input

When calling into hid_map_usage(), the passed event code is
blindly stored as is, even if it doesn't fit in the associated bitmap.

This event code can come from a variety of sources, including devices
masquerading as input devices, only a bit more "programmable".

Instead of taking the event code at face value, check that it actually
fits the corresponding bitmap, and if it doesn't:
- spit out a warning so that we know which device is acting up
- NULLify the bitmap pointer so that we catch unexpected uses

Code paths that can make use of untrusted inputs can now check
that the mapping was indeed correct and bail out if not.

Cc: stable@vger.kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>

static const struct {
	__s32 x;
	__s32 y;
}  hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};

#define map_abs(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_ABS, (c))

#define map_rel(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_REL, (c))

#define map_key(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_KEY, (c))

#define map_led(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_LED, (c))

#define map_abs_clear(c)	hid_map_usage_clear(hidinput, usage, &bit, \
		&max, EV_ABS, (c))

#define map_key_clear(c)	hid_map_usage_clear(hidinput, usage, &bit, \
		&max, EV_KEY, (c))

typedef bool (*hid_usage_cmp_t)(struct hid_usage *usage,
				unsigned int cur_idx, unsigned int val);

static enum power_supply_property hidinput_battery_props[] = {
	POWER_SUPPLY_PROP_PRESENT,
	POWER_SUPPLY_PROP_ONLINE,
	POWER_SUPPLY_PROP_CAPACITY,
	POWER_SUPPLY_PROP_MODEL_NAME,
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_SCOPE,
};

static const struct hid_device_id hid_battery_quirks[] = {
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
			       USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM,
		USB_DEVICE_ID_ELECOM_BM084),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL,
		USB_DEVICE_ID_SYMBOL_SCANNER_3),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK,
		USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD),
	  HID_BATTERY_QUIRK_IGNORE },
	{}
};


static inline int hid_hw_output_report(struct hid_device *hdev, __u8 *buf,
					size_t len)
{
	if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
		return -EINVAL;

	if (hdev->ll_driver->output_report)
		return hdev->ll_driver->output_report(hdev, buf, len);

	return -ENOSYS;
}

struct hid_item {
	unsigned  format;
	__u8      size;
	__u8      type;
	__u8      tag;
	union {
	    __u8   u8;
	    __s8   s8;
	    __u16  u16;
	    __s16  s16;
	    __u32  u32;
	    __s32  s32;
	    __u8  *longdata;
	} data;
}

struct hid_global {
	unsigned usage_page;
	__s32    logical_minimum;
	__s32    logical_maximum;
	__s32    physical_minimum;
	__s32    physical_maximum;
	__s32    unit_exponent;
	unsigned unit;
	unsigned report_id;
	unsigned report_size;
	unsigned report_count;
}

struct hid_local {
	unsigned usage[HID_MAX_USAGES]; /* usage array */
	u8 usage_size[HID_MAX_USAGES]; /* usage size array */
	unsigned collection_index[HID_MAX_USAGES]; /* collection index array */
	unsigned usage_index;
	unsigned usage_minimum;
	unsigned delimiter_depth;
	unsigned delimiter_branch;
}

struct hid_collection {
	int parent_idx; /* device->collection */
	unsigned type;
	unsigned usage;
	unsigned level;
}

struct hid_usage {
	unsigned  hid;			/* hid usage code */
	unsigned  collection_index;	/* index into collection array */
	unsigned  usage_index;		/* index into usage array */
	__s8	  resolution_multiplier;/* Effective Resolution Multiplier
					   (HUT v1.12, 4.3.1), default: 1 */
	/* hidinput data */
	__s8	  wheel_factor;		/* 120/resolution_multiplier */
	__u16     code;			/* input driver code */
	__u8      type;			/* input driver type */
	__s8	  hat_min;		/* hat switch fun */
	__s8	  hat_max;		/* ditto */
	__s8	  hat_dir;		/* ditto */
	__s16	  wheel_accumulated;	/* hi-res wheel */
}

struct hid_input

struct hid_field {
	unsigned  physical;		/* physical usage for this field */
	unsigned  logical;		/* logical usage for this field */
	unsigned  application;		/* application usage for this field */
	struct hid_usage *usage;	/* usage table for this function */
	unsigned  maxusage;		/* maximum usage index */
	unsigned  flags;		/* main-item flags (i.e. volatile,array,constant) */
	unsigned  report_offset;	/* bit offset in the report */
	unsigned  report_size;		/* size of this field in the report */
	unsigned  report_count;		/* number of this field in the report */
	unsigned  report_type;		/* (input,output,feature) */
	__s32    *value;		/* last known value(s) */
	__s32     logical_minimum;
	__s32     logical_maximum;
	__s32     physical_minimum;
	__s32     physical_maximum;
	__s32     unit_exponent;
	unsigned  unit;
	struct hid_report *report;	/* associated report */
	unsigned index;			/* index into report->field[] */
	/* hidinput data */
	struct hid_input *hidinput;	/* associated input structure */
	__u16 dpad;			/* dpad input code */
}


static int hidinput_open(struct input_dev *dev)
{
	struct hid_device *hid = input_get_drvdata(dev);

	return hid_hw_open(hid);
}

static const struct {
	__s32 x;
	__s32 y;
}  hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};

typedef bool (*hid_usage_cmp_t)(struct hid_usage *usage,
				unsigned int cur_idx, unsigned int val);

static enum power_supply_property hidinput_battery_props[] = {
	POWER_SUPPLY_PROP_PRESENT,
	POWER_SUPPLY_PROP_ONLINE,
	POWER_SUPPLY_PROP_CAPACITY,
	POWER_SUPPLY_PROP_MODEL_NAME,
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_SCOPE,
};

static const struct hid_device_id hid_battery_quirks[] = {
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
			       USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM,
		USB_DEVICE_ID_ELECOM_BM084),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL,
		USB_DEVICE_ID_SYMBOL_SCANNER_3),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK,
		USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD),
	  HID_BATTERY_QUIRK_IGNORE },
	{}
};


static int hidinput_scale_battery_capacity(struct hid_device *dev,
					   int value)
{
	if (dev->battery_min < dev->battery_max &&
	    value >= dev->battery_min && value <= dev->battery_max)
		value = ((value - dev->battery_min) * 100) /
			(dev->battery_max - dev->battery_min);

	return value;
}


static bool mt_need_to_apply_feature(struct hid_device *hdev,
				     struct hid_field *field,
				     struct hid_usage *usage,
				     enum latency_mode latency,
				     bool surface_switch,
				     bool button_switch,
				     bool *inputmode_found)
{
	struct mt_device *td = hid_get_drvdata(hdev);
	struct mt_class *cls = &td->mtclass;
	struct hid_report *report = field->report;
	unsigned int index = usage->usage_index;
	char *buf;
	u32 report_len;
	int max;

	switch (usage->hid) {
	case HID_DG_INPUTMODE:
		/*
		 * Some elan panels wrongly declare 2 input mode features,
		 * and silently ignore when we set the value in the second
		 * field. Skip the second feature and hope for the best.
		 */
		if (*inputmode_found)
			return false;

		if (cls->quirks & MT_QUIRK_FORCE_GET_FEATURE) {
			report_len = hid_report_len(report);
			buf = hid_alloc_report_buf(report, GFP_KERNEL);
			if (!buf) {
				hid_err(hdev,
					"failed to allocate buffer for report\n");
				return false;
			}
			hid_hw_raw_request(hdev, report->id, buf, report_len,
					   HID_FEATURE_REPORT,
					   HID_REQ_GET_REPORT);
			kfree(buf);
		}

		field->value[index] = td->inputmode_value;
		*inputmode_found = true;
		return true;

	case HID_DG_CONTACTMAX:
		if (cls->maxcontacts) {
			max = min_t(int, field->logical_maximum,
				    cls->maxcontacts);
			if (field->value[index] != max) {
				field->value[index] = max;
				return true;
			}
		}
		break;

	case HID_DG_LATENCYMODE:
		field->value[index] = latency;
		return true;

	case HID_DG_SURFACESWITCH:
		field->value[index] = surface_switch;
		return true;

	case HID_DG_BUTTONSWITCH:
		field->value[index] = button_switch;
		return true;
	}

	return false; /* no need to update the report */
}

#define MT_QUIRK_FORCE_GET_FEATURE	BIT(13)

enum latency_mode {
	HID_LATENCY_NORMAL = 0,
	HID_LATENCY_HIGH = 1,
}

static const bool mtrue = true;

static const bool mfalse;

static const __s32 mzero;

struct mt_usages {
	struct list_head list;
	__s32 *x, *y, *cx, *cy, *p, *w, *h, *a;
	__s32 *contactid;	/* the device ContactID assigned to this slot */
	bool *tip_state;	/* is the touch valid? */
	bool *inrange_state;	/* is the finger in proximity of the sensor? */
	bool *confidence_state;	/* is the touch made by a finger? */
}

struct mt_application {
	struct list_head list;
	unsigned int application;
	unsigned int report_id;
	struct list_head mt_usages;	/* mt usages list */

	__s32 quirks;

	__s32 *scantime;		/* scantime reported */
	__s32 scantime_logical_max;	/* max value for raw scantime */

	__s32 *raw_cc;			/* contact count in the report */
	int left_button_state;		/* left button state */
	unsigned int mt_flags;		/* flags to pass to input-mt */

	unsigned long *pending_palm_slots;	/* slots where we reported palm
						 * and need to release */

	__u8 num_received;	/* how many contacts we received */
	__u8 num_expected;	/* expected last contact index */
	__u8 buttons_count;	/* number of physical buttons per touchpad */
	__u8 touches_by_report;	/* how many touches are present in one report:
				 * 1 means we should use a serial protocol
				 * > 1 means hybrid (multitouch) protocol
				 */

	__s32 dev_time;		/* the scan time provided by the device */
	unsigned long jiffies;	/* the frame's jiffies */
	int timestamp;		/* the timestamp to be sent */
	int prev_scantime;		/* scantime reported previously */

	bool have_contact_count;
}

struct mt_class {
	__s32 name;	/* MT_CLS */
	__s32 quirks;
	__s32 sn_move;	/* Signal/noise ratio for move events */
	__s32 sn_width;	/* Signal/noise ratio for width events */
	__s32 sn_height;	/* Signal/noise ratio for height events */
	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
	__u8 maxcontacts;
	bool is_indirect;	/* true for touchpads */
	bool export_all_inputs;	/* do not ignore mouse, keyboards, etc... */
}

struct mt_report_data {
	struct list_head list;
	struct hid_report *report;
	struct mt_application *application;
	bool is_mt_collection;
}

struct mt_device {
	struct mt_class mtclass;	/* our mt device class */
	struct timer_list release_timer;	/* to release sticky fingers */
	struct hid_device *hdev;	/* hid_device we're attached to */
	unsigned long mt_io_flags;	/* mt flags (MT_IO_FLAGS_*) */
	__u8 inputmode_value;	/* InputMode HID feature value */
	__u8 maxcontacts;
	bool is_buttonpad;	/* is this device a button pad? */
	bool serial_maybe;	/* need to check for serial protocol */

	struct list_head applications;
	struct list_head reports;
}

static void mt_post_parse_default_settings(struct mt_device *td,
					   struct mt_application *app);

static void mt_post_parse(struct mt_device *td, struct mt_application *app);


static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
				  struct hid_field *field)
{
	return 0;
}


static void mt_report(struct hid_device *hid, struct hid_report *report)
{
	struct mt_device *td = hid_get_drvdata(hid);
	struct hid_field *field = report->field[0];
	struct mt_report_data *rdata;

	if (!(hid->claimed & HID_CLAIMED_INPUT))
		return;

	rdata = mt_find_report_data(td, report);
	if (rdata && rdata->is_mt_collection)
		return mt_touch_report(hid, rdata);

	if (field && field->hidinput && field->hidinput->input)
		input_sync(field->hidinput->input);
}

static const bool mtrue = true;

static const bool mfalse;

static const __s32 mzero;

#define DEFAULT_TRUE	((void *)&mtrue)

#define DEFAULT_FALSE	((void *)&mfalse)

#define DEFAULT_ZERO	((void *)&mzero)

struct mt_usages {
	struct list_head list;
	__s32 *x, *y, *cx, *cy, *p, *w, *h, *a;
	__s32 *contactid;	/* the device ContactID assigned to this slot */
	bool *tip_state;	/* is the touch valid? */
	bool *inrange_state;	/* is the finger in proximity of the sensor? */
	bool *confidence_state;	/* is the touch made by a finger? */
}

struct mt_application {
	struct list_head list;
	unsigned int application;
	unsigned int report_id;
	struct list_head mt_usages;	/* mt usages list */

	__s32 quirks;

	__s32 *scantime;		/* scantime reported */
	__s32 scantime_logical_max;	/* max value for raw scantime */

	__s32 *raw_cc;			/* contact count in the report */
	int left_button_state;		/* left button state */
	unsigned int mt_flags;		/* flags to pass to input-mt */

	unsigned long *pending_palm_slots;	/* slots where we reported palm
						 * and need to release */

	__u8 num_received;	/* how many contacts we received */
	__u8 num_expected;	/* expected last contact index */
	__u8 buttons_count;	/* number of physical buttons per touchpad */
	__u8 touches_by_report;	/* how many touches are present in one report:
				 * 1 means we should use a serial protocol
				 * > 1 means hybrid (multitouch) protocol
				 */

	__s32 dev_time;		/* the scan time provided by the device */
	unsigned long jiffies;	/* the frame's jiffies */
	int timestamp;		/* the timestamp to be sent */
	int prev_scantime;		/* scantime reported previously */

	bool have_contact_count;
}

struct mt_class {
	__s32 name;	/* MT_CLS */
	__s32 quirks;
	__s32 sn_move;	/* Signal/noise ratio for move events */
	__s32 sn_width;	/* Signal/noise ratio for width events */
	__s32 sn_height;	/* Signal/noise ratio for height events */
	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
	__u8 maxcontacts;
	bool is_indirect;	/* true for touchpads */
	bool export_all_inputs;	/* do not ignore mouse, keyboards, etc... */
}

struct mt_report_data {
	struct list_head list;
	struct hid_report *report;
	struct mt_application *application;
	bool is_mt_collection;
}

struct mt_device {
	struct mt_class mtclass;	/* our mt device class */
	struct timer_list release_timer;	/* to release sticky fingers */
	struct hid_device *hdev;	/* hid_device we're attached to */
	unsigned long mt_io_flags;	/* mt flags (MT_IO_FLAGS_*) */
	__u8 inputmode_value;	/* InputMode HID feature value */
	__u8 maxcontacts;
	bool is_buttonpad;	/* is this device a button pad? */
	bool serial_maybe;	/* need to check for serial protocol */

	struct list_head applications;
	struct list_head reports;
}

static void mt_post_parse_default_settings(struct mt_device *td,
					   struct mt_application *app);

static void mt_post_parse(struct mt_device *td, struct mt_application *app);


static int mt_touch_event(struct hid_device *hid, struct hid_field *field,
				struct hid_usage *usage, __s32 value)
{
	/* we will handle the hidinput part later, now remains hiddev */
	if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
		hid->hiddev_hid_event(hid, field, usage, value);

	return 1;
}

static const bool mtrue = true;

static const bool mfalse;

static const __s32 mzero;

struct mt_usages {
	struct list_head list;
	__s32 *x, *y, *cx, *cy, *p, *w, *h, *a;
	__s32 *contactid;	/* the device ContactID assigned to this slot */
	bool *tip_state;	/* is the touch valid? */
	bool *inrange_state;	/* is the finger in proximity of the sensor? */
	bool *confidence_state;	/* is the touch made by a finger? */
}

struct mt_application {
	struct list_head list;
	unsigned int application;
	unsigned int report_id;
	struct list_head mt_usages;	/* mt usages list */

	__s32 quirks;

	__s32 *scantime;		/* scantime reported */
	__s32 scantime_logical_max;	/* max value for raw scantime */

	__s32 *raw_cc;			/* contact count in the report */
	int left_button_state;		/* left button state */
	unsigned int mt_flags;		/* flags to pass to input-mt */

	unsigned long *pending_palm_slots;	/* slots where we reported palm
						 * and need to release */

	__u8 num_received;	/* how many contacts we received */
	__u8 num_expected;	/* expected last contact index */
	__u8 buttons_count;	/* number of physical buttons per touchpad */
	__u8 touches_by_report;	/* how many touches are present in one report:
				 * 1 means we should use a serial protocol
				 * > 1 means hybrid (multitouch) protocol
				 */

	__s32 dev_time;		/* the scan time provided by the device */
	unsigned long jiffies;	/* the frame's jiffies */
	int timestamp;		/* the timestamp to be sent */
	int prev_scantime;		/* scantime reported previously */

	bool have_contact_count;
}

struct mt_class {
	__s32 name;	/* MT_CLS */
	__s32 quirks;
	__s32 sn_move;	/* Signal/noise ratio for move events */
	__s32 sn_width;	/* Signal/noise ratio for width events */
	__s32 sn_height;	/* Signal/noise ratio for height events */
	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
	__u8 maxcontacts;
	bool is_indirect;	/* true for touchpads */
	bool export_all_inputs;	/* do not ignore mouse, keyboards, etc... */
}

struct mt_report_data {
	struct list_head list;
	struct hid_report *report;
	struct mt_application *application;
	bool is_mt_collection;
}

struct mt_device {
	struct mt_class mtclass;	/* our mt device class */
	struct timer_list release_timer;	/* to release sticky fingers */
	struct hid_device *hdev;	/* hid_device we're attached to */
	unsigned long mt_io_flags;	/* mt flags (MT_IO_FLAGS_*) */
	__u8 inputmode_value;	/* InputMode HID feature value */
	__u8 maxcontacts;
	bool is_buttonpad;	/* is this device a button pad? */
	bool serial_maybe;	/* need to check for serial protocol */

	struct list_head applications;
	struct list_head reports;
}

static void mt_post_parse_default_settings(struct mt_device *td,
					   struct mt_application *app);

static void mt_post_parse(struct mt_device *td, struct mt_application *app);


static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, struct hid_field *field)
{
	struct power_supply_desc *psy_desc;
	struct power_supply_config psy_cfg = { .drv_data = dev, };
	unsigned quirks;
	s32 min, max;
	int error;

	if (dev->battery)
		return 0;	/* already initialized? */

	quirks = find_battery_quirk(dev);

	hid_dbg(dev, "device %x:%x:%x %d quirks %d\n",
		dev->bus, dev->vendor, dev->product, dev->version, quirks);

	if (quirks & HID_BATTERY_QUIRK_IGNORE)
		return 0;

	psy_desc = kzalloc(sizeof(*psy_desc), GFP_KERNEL);
	if (!psy_desc)
		return -ENOMEM;

	psy_desc->name = kasprintf(GFP_KERNEL, "hid-%s-battery",
				   strlen(dev->uniq) ?
					dev->uniq : dev_name(&dev->dev));
	if (!psy_desc->name) {
		error = -ENOMEM;
		goto err_free_mem;
	}

	psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
	psy_desc->properties = hidinput_battery_props;
	psy_desc->num_properties = ARRAY_SIZE(hidinput_battery_props);
	psy_desc->use_for_apm = 0;
	psy_desc->get_property = hidinput_get_battery_property;

	min = field->logical_minimum;
	max = field->logical_maximum;

	if (quirks & HID_BATTERY_QUIRK_PERCENT) {
		min = 0;
		max = 100;
	}

	if (quirks & HID_BATTERY_QUIRK_FEATURE)
		report_type = HID_FEATURE_REPORT;

	dev->battery_min = min;
	dev->battery_max = max;
	dev->battery_report_type = report_type;
	dev->battery_report_id = field->report->id;

	/*
	 * Stylus is normally not connected to the device and thus we
	 * can't query the device and get meaningful battery strength.
	 * We have to wait for the device to report it on its own.
	 */
	dev->battery_avoid_query = report_type == HID_INPUT_REPORT &&
				   field->physical == HID_DG_STYLUS;

	dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg);
	if (IS_ERR(dev->battery)) {
		error = PTR_ERR(dev->battery);
		hid_warn(dev, "can't register power supply: %d\n", error);
		goto err_free_name;
	}

	power_supply_powers(dev->battery, &dev->dev);
	return 0;

err_free_name:
	kfree(psy_desc->name);
err_free_mem:
	kfree(psy_desc);
	dev->battery = NULL;
	return error;
}

static const struct {
	__s32 x;
	__s32 y;
}  hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};

#define map_abs(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_ABS, (c))

#define map_rel(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_REL, (c))

#define map_key(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_KEY, (c))

#define map_led(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_LED, (c))

#define map_abs_clear(c)	hid_map_usage_clear(hidinput, usage, &bit, \
		&max, EV_ABS, (c))

#define map_key_clear(c)	hid_map_usage_clear(hidinput, usage, &bit, \
		&max, EV_KEY, (c))

typedef bool (*hid_usage_cmp_t)(struct hid_usage *usage,
				unsigned int cur_idx, unsigned int val);

static enum power_supply_property hidinput_battery_props[] = {
	POWER_SUPPLY_PROP_PRESENT,
	POWER_SUPPLY_PROP_ONLINE,
	POWER_SUPPLY_PROP_CAPACITY,
	POWER_SUPPLY_PROP_MODEL_NAME,
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_SCOPE,
};

#define HID_BATTERY_QUIRK_PERCENT	(1 << 0) /* always reports percent */

#define HID_BATTERY_QUIRK_FEATURE	(1 << 1) /* ask for feature report */

#define HID_BATTERY_QUIRK_IGNORE	(1 << 2) /* completely ignore the battery */

static const struct hid_device_id hid_battery_quirks[] = {
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
			       USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM,
		USB_DEVICE_ID_ELECOM_BM084),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL,
		USB_DEVICE_ID_SYMBOL_SCANNER_3),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK,
		USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD),
	  HID_BATTERY_QUIRK_IGNORE },
	{}
};


static inline int hid_hw_idle(struct hid_device *hdev, int report, int idle,
		int reqtype)
{
	if (hdev->ll_driver->idle)
		return hdev->ll_driver->idle(hdev, report, idle, reqtype);

	return 0;
}


static inline bool hid_is_using_ll_driver(struct hid_device *hdev,
		struct hid_ll_driver *driver)
{
	return hdev->ll_driver == driver;
}


static inline void hid_device_io_stop(struct hid_device *hid) {
	if (!hid->io_started) {
		dev_warn(&hid->dev, "io already stopped\n");
		return;
	}
	hid->io_started = false;
	down(&hid->driver_input_lock);
}


static int hidinput_getkeycode(struct input_dev *dev,
			       struct input_keymap_entry *ke)
{
	struct hid_device *hid = input_get_drvdata(dev);
	struct hid_usage *usage;
	unsigned int scancode, index;

	usage = hidinput_locate_usage(hid, ke, &index);
	if (usage) {
		ke->keycode = usage->type == EV_KEY ?
				usage->code : KEY_RESERVED;
		ke->index = index;
		scancode = usage->hid & (HID_USAGE_PAGE | HID_USAGE);
		ke->len = sizeof(scancode);
		memcpy(ke->scancode, &scancode, sizeof(scancode));
		return 0;
	}

	return -EINVAL;
}


static void mt_post_parse(struct mt_device *td, struct mt_application *app)
{
	if (!app->have_contact_count)
		app->quirks &= ~MT_QUIRK_CONTACT_CNT_ACCURATE;
}

#define MT_QUIRK_CONTACT_CNT_ACCURATE	BIT(12)

static const bool mtrue = true;

static const bool mfalse;

static const __s32 mzero;

#define DEFAULT_TRUE	((void *)&mtrue)

#define DEFAULT_FALSE	((void *)&mfalse)

#define DEFAULT_ZERO	((void *)&mzero)

struct mt_usages {
	struct list_head list;
	__s32 *x, *y, *cx, *cy, *p, *w, *h, *a;
	__s32 *contactid;	/* the device ContactID assigned to this slot */
	bool *tip_state;	/* is the touch valid? */
	bool *inrange_state;	/* is the finger in proximity of the sensor? */
	bool *confidence_state;	/* is the touch made by a finger? */
}

struct mt_application {
	struct list_head list;
	unsigned int application;
	unsigned int report_id;
	struct list_head mt_usages;	/* mt usages list */

	__s32 quirks;

	__s32 *scantime;		/* scantime reported */
	__s32 scantime_logical_max;	/* max value for raw scantime */

	__s32 *raw_cc;			/* contact count in the report */
	int left_button_state;		/* left button state */
	unsigned int mt_flags;		/* flags to pass to input-mt */

	unsigned long *pending_palm_slots;	/* slots where we reported palm
						 * and need to release */

	__u8 num_received;	/* how many contacts we received */
	__u8 num_expected;	/* expected last contact index */
	__u8 buttons_count;	/* number of physical buttons per touchpad */
	__u8 touches_by_report;	/* how many touches are present in one report:
				 * 1 means we should use a serial protocol
				 * > 1 means hybrid (multitouch) protocol
				 */

	__s32 dev_time;		/* the scan time provided by the device */
	unsigned long jiffies;	/* the frame's jiffies */
	int timestamp;		/* the timestamp to be sent */
	int prev_scantime;		/* scantime reported previously */

	bool have_contact_count;
}

struct mt_class {
	__s32 name;	/* MT_CLS */
	__s32 quirks;
	__s32 sn_move;	/* Signal/noise ratio for move events */
	__s32 sn_width;	/* Signal/noise ratio for width events */
	__s32 sn_height;	/* Signal/noise ratio for height events */
	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
	__u8 maxcontacts;
	bool is_indirect;	/* true for touchpads */
	bool export_all_inputs;	/* do not ignore mouse, keyboards, etc... */
}

struct mt_report_data {
	struct list_head list;
	struct hid_report *report;
	struct mt_application *application;
	bool is_mt_collection;
}

struct mt_device {
	struct mt_class mtclass;	/* our mt device class */
	struct timer_list release_timer;	/* to release sticky fingers */
	struct hid_device *hdev;	/* hid_device we're attached to */
	unsigned long mt_io_flags;	/* mt flags (MT_IO_FLAGS_*) */
	__u8 inputmode_value;	/* InputMode HID feature value */
	__u8 maxcontacts;
	bool is_buttonpad;	/* is this device a button pad? */
	bool serial_maybe;	/* need to check for serial protocol */

	struct list_head applications;
	struct list_head reports;
}

static void mt_post_parse_default_settings(struct mt_device *td,
					   struct mt_application *app);


static void hidinput_cleanup_battery(struct hid_device *dev)
{
}


static inline int hid_hw_power(struct hid_device *hdev, int level)
{
	return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0;
}


static void mt_release_contacts(struct hid_device *hid)
{
	struct hid_input *hidinput;
	struct mt_application *application;
	struct mt_device *td = hid_get_drvdata(hid);

	list_for_each_entry(hidinput, &hid->inputs, list) {
		struct input_dev *input_dev = hidinput->input;
		struct input_mt *mt = input_dev->mt;
		int i;

		if (mt) {
			for (i = 0; i < mt->num_slots; i++) {
				input_mt_slot(input_dev, i);
				input_mt_report_slot_inactive(input_dev);
			}
			input_mt_sync_frame(input_dev);
			input_sync(input_dev);
		}
	}

	list_for_each_entry(application, &td->applications, list) {
		application->num_received = 0;
	}
}


static void hidinput_update_battery(struct hid_device *dev, int value)
{
}


static void hidinput_change_resolution_multipliers(struct hid_device *hid)
{
	struct hid_report_enum *rep_enum;
	struct hid_report *rep;
	int ret;

	rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
	list_for_each_entry(rep, &rep_enum->report_list, list) {
		bool update_needed = __hidinput_change_resolution_multipliers(hid,
								     rep, true);

		if (update_needed) {
			ret = __hid_request(hid, rep, HID_REQ_SET_REPORT);
			if (ret) {
				__hidinput_change_resolution_multipliers(hid,
								    rep, false);
				return;
			}
		}
	}

	/* refresh our structs */
	hid_setup_resolution_multiplier(hid);
}


static struct mt_application *mt_find_application(struct mt_device *td,
						  struct hid_report *report)
{
	unsigned int application = report->application;
	struct mt_application *tmp, *mt_application = NULL;

	list_for_each_entry(tmp, &td->applications, list) {
		if (application == tmp->application) {
			if (!(td->mtclass.quirks & MT_QUIRK_SEPARATE_APP_REPORT) ||
			    tmp->report_id == report->id) {
				mt_application = tmp;
				break;
			}
		}
	}

	if (!mt_application)
		mt_application = mt_allocate_application(td, report);

	return mt_application;
}

#define MT_QUIRK_SEPARATE_APP_REPORT	BIT(19)

static const bool mtrue = true;

static const bool mfalse;

static const __s32 mzero;

struct mt_usages {
	struct list_head list;
	__s32 *x, *y, *cx, *cy, *p, *w, *h, *a;
	__s32 *contactid;	/* the device ContactID assigned to this slot */
	bool *tip_state;	/* is the touch valid? */
	bool *inrange_state;	/* is the finger in proximity of the sensor? */
	bool *confidence_state;	/* is the touch made by a finger? */
}

struct mt_application {
	struct list_head list;
	unsigned int application;
	unsigned int report_id;
	struct list_head mt_usages;	/* mt usages list */

	__s32 quirks;

	__s32 *scantime;		/* scantime reported */
	__s32 scantime_logical_max;	/* max value for raw scantime */

	__s32 *raw_cc;			/* contact count in the report */
	int left_button_state;		/* left button state */
	unsigned int mt_flags;		/* flags to pass to input-mt */

	unsigned long *pending_palm_slots;	/* slots where we reported palm
						 * and need to release */

	__u8 num_received;	/* how many contacts we received */
	__u8 num_expected;	/* expected last contact index */
	__u8 buttons_count;	/* number of physical buttons per touchpad */
	__u8 touches_by_report;	/* how many touches are present in one report:
				 * 1 means we should use a serial protocol
				 * > 1 means hybrid (multitouch) protocol
				 */

	__s32 dev_time;		/* the scan time provided by the device */
	unsigned long jiffies;	/* the frame's jiffies */
	int timestamp;		/* the timestamp to be sent */
	int prev_scantime;		/* scantime reported previously */

	bool have_contact_count;
}

struct mt_class {
	__s32 name;	/* MT_CLS */
	__s32 quirks;
	__s32 sn_move;	/* Signal/noise ratio for move events */
	__s32 sn_width;	/* Signal/noise ratio for width events */
	__s32 sn_height;	/* Signal/noise ratio for height events */
	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
	__u8 maxcontacts;
	bool is_indirect;	/* true for touchpads */
	bool export_all_inputs;	/* do not ignore mouse, keyboards, etc... */
}

struct mt_report_data {
	struct list_head list;
	struct hid_report *report;
	struct mt_application *application;
	bool is_mt_collection;
}

struct mt_device {
	struct mt_class mtclass;	/* our mt device class */
	struct timer_list release_timer;	/* to release sticky fingers */
	struct hid_device *hdev;	/* hid_device we're attached to */
	unsigned long mt_io_flags;	/* mt flags (MT_IO_FLAGS_*) */
	__u8 inputmode_value;	/* InputMode HID feature value */
	__u8 maxcontacts;
	bool is_buttonpad;	/* is this device a button pad? */
	bool serial_maybe;	/* need to check for serial protocol */

	struct list_head applications;
	struct list_head reports;
}

static void mt_post_parse_default_settings(struct mt_device *td,
					   struct mt_application *app);

static void mt_post_parse(struct mt_device *td, struct mt_application *app);


static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
{
	struct mt_device *td = hid_get_drvdata(hdev);
	char *name;
	const char *suffix = NULL;
	struct mt_report_data *rdata;
	struct mt_application *mt_application = NULL;
	struct hid_report *report;
	int ret;

	list_for_each_entry(report, &hi->reports, hidinput_list) {
		rdata = mt_find_report_data(td, report);
		if (!rdata) {
			hid_err(hdev, "failed to allocate data for report\n");
			return -ENOMEM;
		}

		mt_application = rdata->application;

		if (rdata->is_mt_collection) {
			ret = mt_touch_input_configured(hdev, hi,
							mt_application);
			if (ret)
				return ret;
		}
	}

	switch (hi->application) {
	case HID_GD_KEYBOARD:
	case HID_GD_KEYPAD:
	case HID_GD_MOUSE:
	case HID_DG_TOUCHPAD:
	case HID_GD_SYSTEM_CONTROL:
	case HID_CP_CONSUMER_CONTROL:
	case HID_GD_WIRELESS_RADIO_CTLS:
	case HID_GD_SYSTEM_MULTIAXIS:
		/* already handled by hid core */
		break;
	case HID_DG_TOUCHSCREEN:
		/* we do not set suffix = "Touchscreen" */
		hi->input->name = hdev->name;
		break;
	case HID_DG_STYLUS:
		/* force BTN_STYLUS to allow tablet matching in udev */
		__set_bit(BTN_STYLUS, hi->input->keybit);
		break;
	case HID_VD_ASUS_CUSTOM_MEDIA_KEYS:
		suffix = "Custom Media Keys";
		break;
	case HID_DG_PEN:
		suffix = "Stylus";
		break;
	default:
		suffix = "UNKNOWN";
		break;
	}

	if (suffix) {
		name = devm_kzalloc(&hi->input->dev,
				    strlen(hdev->name) + strlen(suffix) + 2,
				    GFP_KERNEL);
		if (name) {
			sprintf(name, "%s %s", hdev->name, suffix);
			hi->input->name = name;
		}
	}

	return 0;
}


static void hidinput_cleanup_hidinput(struct hid_device *hid,
		struct hid_input *hidinput)
{
	struct hid_report *report;
	int i, k;

	list_del(&hidinput->list);
	input_free_device(hidinput->input);
	kfree(hidinput->name);

	for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
		if (k == HID_OUTPUT_REPORT &&
			hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)
			continue;

		list_for_each_entry(report, &hid->report_enum[k].report_list,
				    list) {

			for (i = 0; i < report->maxfield; i++)
				if (report->field[i]->hidinput == hidinput)
					report->field[i]->hidinput = NULL;
		}
	}

	kfree(hidinput);
}

static const struct {
	__s32 x;
	__s32 y;
}  hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};

#define map_abs(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_ABS, (c))

#define map_rel(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_REL, (c))

#define map_key(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_KEY, (c))

#define map_led(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_LED, (c))

#define map_abs_clear(c)	hid_map_usage_clear(hidinput, usage, &bit, \
		&max, EV_ABS, (c))

#define map_key_clear(c)	hid_map_usage_clear(hidinput, usage, &bit, \
		&max, EV_KEY, (c))

typedef bool (*hid_usage_cmp_t)(struct hid_usage *usage,
				unsigned int cur_idx, unsigned int val);

static enum power_supply_property hidinput_battery_props[] = {
	POWER_SUPPLY_PROP_PRESENT,
	POWER_SUPPLY_PROP_ONLINE,
	POWER_SUPPLY_PROP_CAPACITY,
	POWER_SUPPLY_PROP_MODEL_NAME,
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_SCOPE,
};

#define HID_BATTERY_QUIRK_FEATURE	(1 << 1) /* ask for feature report */

static const struct hid_device_id hid_battery_quirks[] = {
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
			       USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM,
		USB_DEVICE_ID_ELECOM_BM084),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL,
		USB_DEVICE_ID_SYMBOL_SCANNER_3),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK,
		USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD),
	  HID_BATTERY_QUIRK_IGNORE },
	{}
};


static unsigned find_battery_quirk(struct hid_device *hdev)
{
	unsigned quirks = 0;
	const struct hid_device_id *match;

	match = hid_match_id(hdev, hid_battery_quirks);
	if (match != NULL)
		quirks = match->driver_data;

	return quirks;
}


static int hidinput_query_battery_capacity(struct hid_device *dev)
{
	u8 *buf;
	int ret;

	buf = kmalloc(4, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	ret = hid_hw_raw_request(dev, dev->battery_report_id, buf, 4,
				 dev->battery_report_type, HID_REQ_GET_REPORT);
	if (ret < 2) {
		kfree(buf);
		return -ENODATA;
	}

	ret = hidinput_scale_battery_capacity(dev, buf[1]);
	kfree(buf);
	return ret;
}


static inline void hidinput_configure_usages(struct hid_input *hidinput,
					     struct hid_report *report)
{
	int i, j;

	for (i = 0; i < report->maxfield; i++)
		for (j = 0; j < report->field[i]->maxusage; j++)
			hidinput_configure_usage(hidinput, report->field[i],
						 report->field[i]->usage + j);
}


static inline void hid_set_drvdata(struct hid_device *hdev, void *data)
{
	dev_set_drvdata(&hdev->dev, data);
}


static int mt_event(struct hid_device *hid, struct hid_field *field,
				struct hid_usage *usage, __s32 value)
{
	struct mt_device *td = hid_get_drvdata(hid);
	struct mt_report_data *rdata;

	rdata = mt_find_report_data(td, field->report);
	if (rdata && rdata->is_mt_collection)
		return mt_touch_event(hid, field, usage, value);

	return 0;
}


static int mt_reset_resume(struct hid_device *hdev)
{
	mt_release_contacts(hdev);
	mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true);
	return 0;
}

enum latency_mode {
	HID_LATENCY_NORMAL = 0,
	HID_LATENCY_HIGH = 1,
}

static const bool mtrue = true;

static const bool mfalse;

static const __s32 mzero;

struct mt_usages {
	struct list_head list;
	__s32 *x, *y, *cx, *cy, *p, *w, *h, *a;
	__s32 *contactid;	/* the device ContactID assigned to this slot */
	bool *tip_state;	/* is the touch valid? */
	bool *inrange_state;	/* is the finger in proximity of the sensor? */
	bool *confidence_state;	/* is the touch made by a finger? */
}

struct mt_application {
	struct list_head list;
	unsigned int application;
	unsigned int report_id;
	struct list_head mt_usages;	/* mt usages list */

	__s32 quirks;

	__s32 *scantime;		/* scantime reported */
	__s32 scantime_logical_max;	/* max value for raw scantime */

	__s32 *raw_cc;			/* contact count in the report */
	int left_button_state;		/* left button state */
	unsigned int mt_flags;		/* flags to pass to input-mt */

	unsigned long *pending_palm_slots;	/* slots where we reported palm
						 * and need to release */

	__u8 num_received;	/* how many contacts we received */
	__u8 num_expected;	/* expected last contact index */
	__u8 buttons_count;	/* number of physical buttons per touchpad */
	__u8 touches_by_report;	/* how many touches are present in one report:
				 * 1 means we should use a serial protocol
				 * > 1 means hybrid (multitouch) protocol
				 */

	__s32 dev_time;		/* the scan time provided by the device */
	unsigned long jiffies;	/* the frame's jiffies */
	int timestamp;		/* the timestamp to be sent */
	int prev_scantime;		/* scantime reported previously */

	bool have_contact_count;
}

struct mt_class {
	__s32 name;	/* MT_CLS */
	__s32 quirks;
	__s32 sn_move;	/* Signal/noise ratio for move events */
	__s32 sn_width;	/* Signal/noise ratio for width events */
	__s32 sn_height;	/* Signal/noise ratio for height events */
	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
	__u8 maxcontacts;
	bool is_indirect;	/* true for touchpads */
	bool export_all_inputs;	/* do not ignore mouse, keyboards, etc... */
}

struct mt_report_data {
	struct list_head list;
	struct hid_report *report;
	struct mt_application *application;
	bool is_mt_collection;
}

struct mt_device {
	struct mt_class mtclass;	/* our mt device class */
	struct timer_list release_timer;	/* to release sticky fingers */
	struct hid_device *hdev;	/* hid_device we're attached to */
	unsigned long mt_io_flags;	/* mt flags (MT_IO_FLAGS_*) */
	__u8 inputmode_value;	/* InputMode HID feature value */
	__u8 maxcontacts;
	bool is_buttonpad;	/* is this device a button pad? */
	bool serial_maybe;	/* need to check for serial protocol */

	struct list_head applications;
	struct list_head reports;
}

static void mt_post_parse_default_settings(struct mt_device *td,
					   struct mt_application *app);

static void mt_post_parse(struct mt_device *td, struct mt_application *app);


static struct hid_usage *hidinput_find_key(struct hid_device *hid,
					   hid_usage_cmp_t match,
					   unsigned int value,
					   unsigned int *usage_idx)
{
	unsigned int i, j, k, cur_idx = 0;
	struct hid_report *report;
	struct hid_usage *usage;

	for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
		list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
			for (i = 0; i < report->maxfield; i++) {
				for (j = 0; j < report->field[i]->maxusage; j++) {
					usage = report->field[i]->usage + j;
					if (usage->type == EV_KEY || usage->type == 0) {
						if (match(usage, cur_idx, value)) {
							if (usage_idx)
								*usage_idx = cur_idx;
							return usage;
						}
						cur_idx++;
					}
				}
			}
		}
	}
	return NULL;
}


static void mt_feature_mapping(struct hid_device *hdev,
		struct hid_field *field, struct hid_usage *usage)
{
	struct mt_device *td = hid_get_drvdata(hdev);

	switch (usage->hid) {
	case HID_DG_CONTACTMAX:
		mt_get_feature(hdev, field->report);

		td->maxcontacts = field->value[0];
		if (!td->maxcontacts &&
		    field->logical_maximum <= MT_MAX_MAXCONTACT)
			td->maxcontacts = field->logical_maximum;
		if (td->mtclass.maxcontacts)
			/* check if the maxcontacts is given by the class */
			td->maxcontacts = td->mtclass.maxcontacts;

		break;
	case HID_DG_BUTTONTYPE:
		if (usage->usage_index >= field->report_count) {
			dev_err(&hdev->dev, "HID_DG_BUTTONTYPE out of range\n");
			break;
		}

		mt_get_feature(hdev, field->report);
		if (field->value[usage->usage_index] == MT_BUTTONTYPE_CLICKPAD)
			td->is_buttonpad = true;

		break;
	case 0xff0000c5:
		/* Retrieve the Win8 blob once to enable some devices */
		if (usage->usage_index == 0)
			mt_get_feature(hdev, field->report);
		break;
	}
}

#define MT_BUTTONTYPE_CLICKPAD		0

static const bool mtrue = true;

static const bool mfalse;

static const __s32 mzero;

#define DEFAULT_TRUE	((void *)&mtrue)

#define DEFAULT_FALSE	((void *)&mfalse)

#define DEFAULT_ZERO	((void *)&mzero)

struct mt_usages {
	struct list_head list;
	__s32 *x, *y, *cx, *cy, *p, *w, *h, *a;
	__s32 *contactid;	/* the device ContactID assigned to this slot */
	bool *tip_state;	/* is the touch valid? */
	bool *inrange_state;	/* is the finger in proximity of the sensor? */
	bool *confidence_state;	/* is the touch made by a finger? */
}

struct mt_application {
	struct list_head list;
	unsigned int application;
	unsigned int report_id;
	struct list_head mt_usages;	/* mt usages list */

	__s32 quirks;

	__s32 *scantime;		/* scantime reported */
	__s32 scantime_logical_max;	/* max value for raw scantime */

	__s32 *raw_cc;			/* contact count in the report */
	int left_button_state;		/* left button state */
	unsigned int mt_flags;		/* flags to pass to input-mt */

	unsigned long *pending_palm_slots;	/* slots where we reported palm
						 * and need to release */

	__u8 num_received;	/* how many contacts we received */
	__u8 num_expected;	/* expected last contact index */
	__u8 buttons_count;	/* number of physical buttons per touchpad */
	__u8 touches_by_report;	/* how many touches are present in one report:
				 * 1 means we should use a serial protocol
				 * > 1 means hybrid (multitouch) protocol
				 */

	__s32 dev_time;		/* the scan time provided by the device */
	unsigned long jiffies;	/* the frame's jiffies */
	int timestamp;		/* the timestamp to be sent */
	int prev_scantime;		/* scantime reported previously */

	bool have_contact_count;
}

struct mt_class {
	__s32 name;	/* MT_CLS */
	__s32 quirks;
	__s32 sn_move;	/* Signal/noise ratio for move events */
	__s32 sn_width;	/* Signal/noise ratio for width events */
	__s32 sn_height;	/* Signal/noise ratio for height events */
	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
	__u8 maxcontacts;
	bool is_indirect;	/* true for touchpads */
	bool export_all_inputs;	/* do not ignore mouse, keyboards, etc... */
}

struct mt_report_data {
	struct list_head list;
	struct hid_report *report;
	struct mt_application *application;
	bool is_mt_collection;
}

struct mt_device {
	struct mt_class mtclass;	/* our mt device class */
	struct timer_list release_timer;	/* to release sticky fingers */
	struct hid_device *hdev;	/* hid_device we're attached to */
	unsigned long mt_io_flags;	/* mt flags (MT_IO_FLAGS_*) */
	__u8 inputmode_value;	/* InputMode HID feature value */
	__u8 maxcontacts;
	bool is_buttonpad;	/* is this device a button pad? */
	bool serial_maybe;	/* need to check for serial protocol */

	struct list_head applications;
	struct list_head reports;
}

static void mt_post_parse_default_settings(struct mt_device *td,
					   struct mt_application *app);

static void mt_post_parse(struct mt_device *td, struct mt_application *app);


static void set_abs(struct input_dev *input, unsigned int code,
		struct hid_field *field, int snratio)
{
	int fmin = field->logical_minimum;
	int fmax = field->logical_maximum;
	int fuzz = snratio ? (fmax - fmin) / snratio : 0;
	input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
	input_abs_set_res(input, code, hidinput_calc_abs_res(field, code));
}


static void mt_remove(struct hid_device *hdev)
{
	struct mt_device *td = hid_get_drvdata(hdev);

	del_timer_sync(&td->release_timer);

	sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
	hid_hw_stop(hdev);
}


static void mt_set_modes(struct hid_device *hdev, enum latency_mode latency,
			 bool surface_switch, bool button_switch)
{
	struct hid_report_enum *rep_enum;
	struct hid_report *rep;
	struct hid_usage *usage;
	int i, j;
	bool update_report;
	bool inputmode_found = false;

	rep_enum = &hdev->report_enum[HID_FEATURE_REPORT];
	list_for_each_entry(rep, &rep_enum->report_list, list) {
		update_report = false;

		for (i = 0; i < rep->maxfield; i++) {
			/* Ignore if report count is out of bounds. */
			if (rep->field[i]->report_count < 1)
				continue;

			for (j = 0; j < rep->field[i]->maxusage; j++) {
				usage = &rep->field[i]->usage[j];

				if (mt_need_to_apply_feature(hdev,
							     rep->field[i],
							     usage,
							     latency,
							     surface_switch,
							     button_switch,
							     &inputmode_found))
					update_report = true;
			}
		}

		if (update_report)
			hid_hw_request(hdev, rep, HID_REQ_SET_REPORT);
	}
}

enum latency_mode {
	HID_LATENCY_NORMAL = 0,
	HID_LATENCY_HIGH = 1,
}

static const bool mtrue = true;

static const bool mfalse;

static const __s32 mzero;

#define DEFAULT_TRUE	((void *)&mtrue)

#define DEFAULT_FALSE	((void *)&mfalse)

#define DEFAULT_ZERO	((void *)&mzero)

struct mt_usages {
	struct list_head list;
	__s32 *x, *y, *cx, *cy, *p, *w, *h, *a;
	__s32 *contactid;	/* the device ContactID assigned to this slot */
	bool *tip_state;	/* is the touch valid? */
	bool *inrange_state;	/* is the finger in proximity of the sensor? */
	bool *confidence_state;	/* is the touch made by a finger? */
}

struct mt_application {
	struct list_head list;
	unsigned int application;
	unsigned int report_id;
	struct list_head mt_usages;	/* mt usages list */

	__s32 quirks;

	__s32 *scantime;		/* scantime reported */
	__s32 scantime_logical_max;	/* max value for raw scantime */

	__s32 *raw_cc;			/* contact count in the report */
	int left_button_state;		/* left button state */
	unsigned int mt_flags;		/* flags to pass to input-mt */

	unsigned long *pending_palm_slots;	/* slots where we reported palm
						 * and need to release */

	__u8 num_received;	/* how many contacts we received */
	__u8 num_expected;	/* expected last contact index */
	__u8 buttons_count;	/* number of physical buttons per touchpad */
	__u8 touches_by_report;	/* how many touches are present in one report:
				 * 1 means we should use a serial protocol
				 * > 1 means hybrid (multitouch) protocol
				 */

	__s32 dev_time;		/* the scan time provided by the device */
	unsigned long jiffies;	/* the frame's jiffies */
	int timestamp;		/* the timestamp to be sent */
	int prev_scantime;		/* scantime reported previously */

	bool have_contact_count;
}

struct mt_class {
	__s32 name;	/* MT_CLS */
	__s32 quirks;
	__s32 sn_move;	/* Signal/noise ratio for move events */
	__s32 sn_width;	/* Signal/noise ratio for width events */
	__s32 sn_height;	/* Signal/noise ratio for height events */
	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
	__u8 maxcontacts;
	bool is_indirect;	/* true for touchpads */
	bool export_all_inputs;	/* do not ignore mouse, keyboards, etc... */
}

struct mt_report_data {
	struct list_head list;
	struct hid_report *report;
	struct mt_application *application;
	bool is_mt_collection;
}

struct mt_device {
	struct mt_class mtclass;	/* our mt device class */
	struct timer_list release_timer;	/* to release sticky fingers */
	struct hid_device *hdev;	/* hid_device we're attached to */
	unsigned long mt_io_flags;	/* mt flags (MT_IO_FLAGS_*) */
	__u8 inputmode_value;	/* InputMode HID feature value */
	__u8 maxcontacts;
	bool is_buttonpad;	/* is this device a button pad? */
	bool serial_maybe;	/* need to check for serial protocol */

	struct list_head applications;
	struct list_head reports;
}

static void mt_post_parse_default_settings(struct mt_device *td,
					   struct mt_application *app);


static inline void hid_device_io_start(struct hid_device *hid) {
	if (hid->io_started) {
		dev_warn(&hid->dev, "io already started\n");
		return;
	}
	hid->io_started = true;
	up(&hid->driver_input_lock);
}


static struct mt_application *mt_allocate_application(struct mt_device *td,
						      struct hid_report *report)
{
	unsigned int application = report->application;
	struct mt_application *mt_application;

	mt_application = devm_kzalloc(&td->hdev->dev, sizeof(*mt_application),
				      GFP_KERNEL);
	if (!mt_application)
		return NULL;

	mt_application->application = application;
	INIT_LIST_HEAD(&mt_application->mt_usages);

	if (application == HID_DG_TOUCHSCREEN)
		mt_application->mt_flags |= INPUT_MT_DIRECT;

	/*
	 * Model touchscreens providing buttons as touchpads.
	 */
	if (application == HID_DG_TOUCHPAD) {
		mt_application->mt_flags |= INPUT_MT_POINTER;
		td->inputmode_value = MT_INPUTMODE_TOUCHPAD;
	}

	mt_application->scantime = DEFAULT_ZERO;
	mt_application->raw_cc = DEFAULT_ZERO;
	mt_application->quirks = td->mtclass.quirks;
	mt_application->report_id = report->id;

	list_add_tail(&mt_application->list, &td->applications);

	return mt_application;
}

#define MT_INPUTMODE_TOUCHPAD		0x03

static const bool mtrue = true;

static const bool mfalse;

static const __s32 mzero;

#define DEFAULT_ZERO	((void *)&mzero)

struct mt_usages {
	struct list_head list;
	__s32 *x, *y, *cx, *cy, *p, *w, *h, *a;
	__s32 *contactid;	/* the device ContactID assigned to this slot */
	bool *tip_state;	/* is the touch valid? */
	bool *inrange_state;	/* is the finger in proximity of the sensor? */
	bool *confidence_state;	/* is the touch made by a finger? */
}

struct mt_application {
	struct list_head list;
	unsigned int application;
	unsigned int report_id;
	struct list_head mt_usages;	/* mt usages list */

	__s32 quirks;

	__s32 *scantime;		/* scantime reported */
	__s32 scantime_logical_max;	/* max value for raw scantime */

	__s32 *raw_cc;			/* contact count in the report */
	int left_button_state;		/* left button state */
	unsigned int mt_flags;		/* flags to pass to input-mt */

	unsigned long *pending_palm_slots;	/* slots where we reported palm
						 * and need to release */

	__u8 num_received;	/* how many contacts we received */
	__u8 num_expected;	/* expected last contact index */
	__u8 buttons_count;	/* number of physical buttons per touchpad */
	__u8 touches_by_report;	/* how many touches are present in one report:
				 * 1 means we should use a serial protocol
				 * > 1 means hybrid (multitouch) protocol
				 */

	__s32 dev_time;		/* the scan time provided by the device */
	unsigned long jiffies;	/* the frame's jiffies */
	int timestamp;		/* the timestamp to be sent */
	int prev_scantime;		/* scantime reported previously */

	bool have_contact_count;
}

struct mt_class {
	__s32 name;	/* MT_CLS */
	__s32 quirks;
	__s32 sn_move;	/* Signal/noise ratio for move events */
	__s32 sn_width;	/* Signal/noise ratio for width events */
	__s32 sn_height;	/* Signal/noise ratio for height events */
	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
	__u8 maxcontacts;
	bool is_indirect;	/* true for touchpads */
	bool export_all_inputs;	/* do not ignore mouse, keyboards, etc... */
}

struct mt_report_data {
	struct list_head list;
	struct hid_report *report;
	struct mt_application *application;
	bool is_mt_collection;
}

struct mt_device {
	struct mt_class mtclass;	/* our mt device class */
	struct timer_list release_timer;	/* to release sticky fingers */
	struct hid_device *hdev;	/* hid_device we're attached to */
	unsigned long mt_io_flags;	/* mt flags (MT_IO_FLAGS_*) */
	__u8 inputmode_value;	/* InputMode HID feature value */
	__u8 maxcontacts;
	bool is_buttonpad;	/* is this device a button pad? */
	bool serial_maybe;	/* need to check for serial protocol */

	struct list_head applications;
	struct list_head reports;
}

static void mt_post_parse_default_settings(struct mt_device *td,
					   struct mt_application *app);

static void mt_post_parse(struct mt_device *td, struct mt_application *app);


static struct mt_report_data *mt_allocate_report_data(struct mt_device *td,
						      struct hid_report *report)
{
	struct mt_report_data *rdata;
	struct hid_field *field;
	int r, n;

	rdata = devm_kzalloc(&td->hdev->dev, sizeof(*rdata), GFP_KERNEL);
	if (!rdata)
		return NULL;

	rdata->report = report;
	rdata->application = mt_find_application(td, report);

	if (!rdata->application) {
		devm_kfree(&td->hdev->dev, rdata);
		return NULL;
	}

	for (r = 0; r < report->maxfield; r++) {
		field = report->field[r];

		if (!(HID_MAIN_ITEM_VARIABLE & field->flags))
			continue;

		for (n = 0; n < field->report_count; n++) {
			if (field->usage[n].hid == HID_DG_CONTACTID)
				rdata->is_mt_collection = true;
		}
	}

	list_add_tail(&rdata->list, &td->reports);

	return rdata;
}


static void mt_process_mt_event(struct hid_device *hid,
				struct mt_application *app,
				struct hid_field *field,
				struct hid_usage *usage,
				__s32 value,
				bool first_packet)
{
	__s32 quirks = app->quirks;
	struct input_dev *input = field->hidinput->input;

	if (!usage->type || !(hid->claimed & HID_CLAIMED_INPUT))
		return;

	if (quirks & MT_QUIRK_WIN8_PTP_BUTTONS) {

		/*
		 * For Win8 PTP touchpads we should only look at
		 * non finger/touch events in the first_packet of a
		 * (possible) multi-packet frame.
		 */
		if (!first_packet)
			return;

		/*
		 * For Win8 PTP touchpads we map both the clickpad click
		 * and any "external" left buttons to BTN_LEFT if a
		 * device claims to have both we need to report 1 for
		 * BTN_LEFT if either is pressed, so we or all values
		 * together and report the result in mt_sync_frame().
		 */
		if (usage->type == EV_KEY && usage->code == BTN_LEFT) {
			app->left_button_state |= value;
			return;
		}
	}

	input_event(input, usage->type, usage->code, value);
}

#define MT_QUIRK_WIN8_PTP_BUTTONS	BIT(18)

static const bool mtrue = true;

static const bool mfalse;

static const __s32 mzero;

#define DEFAULT_TRUE	((void *)&mtrue)

#define DEFAULT_FALSE	((void *)&mfalse)

#define DEFAULT_ZERO	((void *)&mzero)

struct mt_usages {
	struct list_head list;
	__s32 *x, *y, *cx, *cy, *p, *w, *h, *a;
	__s32 *contactid;	/* the device ContactID assigned to this slot */
	bool *tip_state;	/* is the touch valid? */
	bool *inrange_state;	/* is the finger in proximity of the sensor? */
	bool *confidence_state;	/* is the touch made by a finger? */
}

struct mt_application {
	struct list_head list;
	unsigned int application;
	unsigned int report_id;
	struct list_head mt_usages;	/* mt usages list */

	__s32 quirks;

	__s32 *scantime;		/* scantime reported */
	__s32 scantime_logical_max;	/* max value for raw scantime */

	__s32 *raw_cc;			/* contact count in the report */
	int left_button_state;		/* left button state */
	unsigned int mt_flags;		/* flags to pass to input-mt */

	unsigned long *pending_palm_slots;	/* slots where we reported palm
						 * and need to release */

	__u8 num_received;	/* how many contacts we received */
	__u8 num_expected;	/* expected last contact index */
	__u8 buttons_count;	/* number of physical buttons per touchpad */
	__u8 touches_by_report;	/* how many touches are present in one report:
				 * 1 means we should use a serial protocol
				 * > 1 means hybrid (multitouch) protocol
				 */

	__s32 dev_time;		/* the scan time provided by the device */
	unsigned long jiffies;	/* the frame's jiffies */
	int timestamp;		/* the timestamp to be sent */
	int prev_scantime;		/* scantime reported previously */

	bool have_contact_count;
}

struct mt_class {
	__s32 name;	/* MT_CLS */
	__s32 quirks;
	__s32 sn_move;	/* Signal/noise ratio for move events */
	__s32 sn_width;	/* Signal/noise ratio for width events */
	__s32 sn_height;	/* Signal/noise ratio for height events */
	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
	__u8 maxcontacts;
	bool is_indirect;	/* true for touchpads */
	bool export_all_inputs;	/* do not ignore mouse, keyboards, etc... */
}

struct mt_report_data {
	struct list_head list;
	struct hid_report *report;
	struct mt_application *application;
	bool is_mt_collection;
}

struct mt_device {
	struct mt_class mtclass;	/* our mt device class */
	struct timer_list release_timer;	/* to release sticky fingers */
	struct hid_device *hdev;	/* hid_device we're attached to */
	unsigned long mt_io_flags;	/* mt flags (MT_IO_FLAGS_*) */
	__u8 inputmode_value;	/* InputMode HID feature value */
	__u8 maxcontacts;
	bool is_buttonpad;	/* is this device a button pad? */
	bool serial_maybe;	/* need to check for serial protocol */

	struct list_head applications;
	struct list_head reports;
}

static void mt_post_parse_default_settings(struct mt_device *td,
					   struct mt_application *app);


static void mt_expired_timeout(struct timer_list *t)
{
	struct mt_device *td = from_timer(td, t, release_timer);
	struct hid_device *hdev = td->hdev;

	/*
	 * An input report came in just before we release the sticky fingers,
	 * it will take care of the sticky fingers.
	 */
	if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
		return;
	if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags))
		mt_release_contacts(hdev);
	clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
}

#define MT_IO_FLAGS_RUNNING		0

#define MT_IO_FLAGS_PENDING_SLOTS	2

static const bool mtrue = true;

static const bool mfalse;

static const __s32 mzero;

#define DEFAULT_TRUE	((void *)&mtrue)

#define DEFAULT_FALSE	((void *)&mfalse)

#define DEFAULT_ZERO	((void *)&mzero)

struct mt_usages {
	struct list_head list;
	__s32 *x, *y, *cx, *cy, *p, *w, *h, *a;
	__s32 *contactid;	/* the device ContactID assigned to this slot */
	bool *tip_state;	/* is the touch valid? */
	bool *inrange_state;	/* is the finger in proximity of the sensor? */
	bool *confidence_state;	/* is the touch made by a finger? */
}

struct mt_application {
	struct list_head list;
	unsigned int application;
	unsigned int report_id;
	struct list_head mt_usages;	/* mt usages list */

	__s32 quirks;

	__s32 *scantime;		/* scantime reported */
	__s32 scantime_logical_max;	/* max value for raw scantime */

	__s32 *raw_cc;			/* contact count in the report */
	int left_button_state;		/* left button state */
	unsigned int mt_flags;		/* flags to pass to input-mt */

	unsigned long *pending_palm_slots;	/* slots where we reported palm
						 * and need to release */

	__u8 num_received;	/* how many contacts we received */
	__u8 num_expected;	/* expected last contact index */
	__u8 buttons_count;	/* number of physical buttons per touchpad */
	__u8 touches_by_report;	/* how many touches are present in one report:
				 * 1 means we should use a serial protocol
				 * > 1 means hybrid (multitouch) protocol
				 */

	__s32 dev_time;		/* the scan time provided by the device */
	unsigned long jiffies;	/* the frame's jiffies */
	int timestamp;		/* the timestamp to be sent */
	int prev_scantime;		/* scantime reported previously */

	bool have_contact_count;
}

struct mt_class {
	__s32 name;	/* MT_CLS */
	__s32 quirks;
	__s32 sn_move;	/* Signal/noise ratio for move events */
	__s32 sn_width;	/* Signal/noise ratio for width events */
	__s32 sn_height;	/* Signal/noise ratio for height events */
	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
	__u8 maxcontacts;
	bool is_indirect;	/* true for touchpads */
	bool export_all_inputs;	/* do not ignore mouse, keyboards, etc... */
}

struct mt_report_data {
	struct list_head list;
	struct hid_report *report;
	struct mt_application *application;
	bool is_mt_collection;
}

struct mt_device {
	struct mt_class mtclass;	/* our mt device class */
	struct timer_list release_timer;	/* to release sticky fingers */
	struct hid_device *hdev;	/* hid_device we're attached to */
	unsigned long mt_io_flags;	/* mt flags (MT_IO_FLAGS_*) */
	__u8 inputmode_value;	/* InputMode HID feature value */
	__u8 maxcontacts;
	bool is_buttonpad;	/* is this device a button pad? */
	bool serial_maybe;	/* need to check for serial protocol */

	struct list_head applications;
	struct list_head reports;
}

static void mt_post_parse_default_settings(struct mt_device *td,
					   struct mt_application *app);


static int hidinput_setkeycode(struct input_dev *dev,
			       const struct input_keymap_entry *ke,
			       unsigned int *old_keycode)
{
	struct hid_device *hid = input_get_drvdata(dev);
	struct hid_usage *usage;

	usage = hidinput_locate_usage(hid, ke, NULL);
	if (usage) {
		*old_keycode = usage->type == EV_KEY ?
				usage->code : KEY_RESERVED;
		usage->code = ke->keycode;

		clear_bit(*old_keycode, dev->keybit);
		set_bit(usage->code, dev->keybit);
		dbg_hid("Assigned keycode %d to HID usage code %x\n",
			usage->code, usage->hid);

		/*
		 * Set the keybit for the old keycode if the old keycode is used
		 * by another key
		 */
		if (hidinput_find_key(hid, match_keycode, *old_keycode, NULL))
			set_bit(*old_keycode, dev->keybit);

		return 0;
	}

	return -EINVAL;
}

static const struct {
	__s32 x;
	__s32 y;
}  hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};

#define map_abs(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_ABS, (c))

#define map_rel(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_REL, (c))

#define map_key(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_KEY, (c))

#define map_led(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_LED, (c))

#define map_abs_clear(c)	hid_map_usage_clear(hidinput, usage, &bit, \
		&max, EV_ABS, (c))

#define map_key_clear(c)	hid_map_usage_clear(hidinput, usage, &bit, \
		&max, EV_KEY, (c))

typedef bool (*hid_usage_cmp_t)(struct hid_usage *usage,
				unsigned int cur_idx, unsigned int val);

static enum power_supply_property hidinput_battery_props[] = {
	POWER_SUPPLY_PROP_PRESENT,
	POWER_SUPPLY_PROP_ONLINE,
	POWER_SUPPLY_PROP_CAPACITY,
	POWER_SUPPLY_PROP_MODEL_NAME,
	POWER_SUPPLY_PROP_STATUS,
	POWER_SUPPLY_PROP_SCOPE,
};

#define HID_BATTERY_QUIRK_FEATURE	(1 << 1) /* ask for feature report */

#define HID_BATTERY_QUIRK_IGNORE	(1 << 2) /* completely ignore the battery */

static const struct hid_device_id hid_battery_quirks[] = {
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
			       USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM,
		USB_DEVICE_ID_ELECOM_BM084),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL,
		USB_DEVICE_ID_SYMBOL_SCANNER_3),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK,
		USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD),
	  HID_BATTERY_QUIRK_IGNORE },
	{}
};


void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
{
	struct input_dev *input;
	unsigned *quirks = &hid->quirks;

	if (!usage->type)
		return;

	if (usage->type == EV_PWR) {
		hidinput_update_battery(hid, value);
		return;
	}

	if (!field->hidinput)
		return;

	input = field->hidinput->input;

	if (usage->hat_min < usage->hat_max || usage->hat_dir) {
		int hat_dir = usage->hat_dir;
		if (!hat_dir)
			hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1;
		if (hat_dir < 0 || hat_dir > 8) hat_dir = 0;
		input_event(input, usage->type, usage->code    , hid_hat_to_axis[hat_dir].x);
		input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[hat_dir].y);
		return;
	}

	if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */
		*quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT);
		return;
	}

	if (usage->hid == (HID_UP_DIGITIZER | 0x0032)) { /* InRange */
		if (value) {
			input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1);
			return;
		}
		input_event(input, usage->type, usage->code, 0);
		input_event(input, usage->type, BTN_TOOL_RUBBER, 0);
		return;
	}

	if (usage->hid == (HID_UP_DIGITIZER | 0x0030) && (*quirks & HID_QUIRK_NOTOUCH)) { /* Pressure */
		int a = field->logical_minimum;
		int b = field->logical_maximum;
		input_event(input, EV_KEY, BTN_TOUCH, value > a + ((b - a) >> 3));
	}

	if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */
		dbg_hid("Maximum Effects - %d\n",value);
		return;
	}

	if (usage->hid == (HID_UP_PID | 0x7fUL)) {
		dbg_hid("PID Pool Report\n");
		return;
	}

	if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */
		return;

	if ((usage->type == EV_REL) && (usage->code == REL_WHEEL_HI_RES ||
					usage->code == REL_HWHEEL_HI_RES)) {
		hidinput_handle_scroll(usage, input, value);
		return;
	}

	if ((usage->type == EV_ABS) && (field->flags & HID_MAIN_ITEM_RELATIVE) &&
			(usage->code == ABS_VOLUME)) {
		int count = abs(value);
		int direction = value > 0 ? KEY_VOLUMEUP : KEY_VOLUMEDOWN;
		int i;

		for (i = 0; i < count; i++) {
			input_event(input, EV_KEY, direction, 1);
			input_sync(input);
			input_event(input, EV_KEY, direction, 0);
			input_sync(input);
		}
		return;
	}

	/*
	 * Ignore out-of-range values as per HID specification,
	 * section 5.10 and 6.2.25, when NULL state bit is present.
	 * When it's not, clamp the value to match Microsoft's input
	 * driver as mentioned in "Required HID usages for digitizers":
	 * https://msdn.microsoft.com/en-us/library/windows/hardware/dn672278(v=vs.85).asp
	 *
	 * The logical_minimum < logical_maximum check is done so that we
	 * don't unintentionally discard values sent by devices which
	 * don't specify logical min and max.
	 */
	if ((field->flags & HID_MAIN_ITEM_VARIABLE) &&
	    (field->logical_minimum < field->logical_maximum)) {
		if (field->flags & HID_MAIN_ITEM_NULL_STATE &&
		    (value < field->logical_minimum ||
		     value > field->logical_maximum)) {
			dbg_hid("Ignoring out-of-range value %x\n", value);
			return;
		}
		value = clamp(value,
			      field->logical_minimum,
			      field->logical_maximum);
	}

	/*
	 * Ignore reports for absolute data if the data didn't change. This is
	 * not only an optimization but also fixes 'dead' key reports. Some
	 * RollOver implementations for localized keys (like BACKSLASH/PIPE; HID
	 * 0x31 and 0x32) report multiple keys, even though a localized keyboard
	 * can only have one of them physically available. The 'dead' keys
	 * report constant 0. As all map to the same keycode, they'd confuse
	 * the input layer. If we filter the 'dead' keys on the HID level, we
	 * skip the keycode translation and only forward real events.
	 */
	if (!(field->flags & (HID_MAIN_ITEM_RELATIVE |
	                      HID_MAIN_ITEM_BUFFERED_BYTE)) &&
			      (field->flags & HID_MAIN_ITEM_VARIABLE) &&
	    usage->usage_index < field->maxusage &&
	    value == field->value[usage->usage_index])
		return;

	/* report the usage code as scancode if the key status has changed */
	if (usage->type == EV_KEY &&
	    (!test_bit(usage->code, input->key)) == value)
		input_event(input, EV_MSC, MSC_SCAN, usage->hid);

	input_event(input, usage->type, usage->code, value);

	if ((field->flags & HID_MAIN_ITEM_RELATIVE) &&
	    usage->type == EV_KEY && value) {
		input_sync(input);
		input_event(input, usage->type, usage->code, 0);
	}
}


static void mt_store_field(struct hid_device *hdev,
			   struct mt_application *application,
			   __s32 *value,
			   size_t offset)
{
	struct mt_usages *usage;
	__s32 **target;

	if (list_empty(&application->mt_usages))
		usage = mt_allocate_usage(hdev, application);
	else
		usage = list_last_entry(&application->mt_usages,
					struct mt_usages,
					list);

	if (!usage)
		return;

	target = (__s32 **)((char *)usage + offset);

	/* the value has already been filled, create a new slot */
	if (*target != DEFAULT_TRUE &&
	    *target != DEFAULT_FALSE &&
	    *target != DEFAULT_ZERO) {
		if (usage->contactid == DEFAULT_ZERO ||
		    usage->x == DEFAULT_ZERO ||
		    usage->y == DEFAULT_ZERO) {
			hid_dbg(hdev,
				"ignoring duplicate usage on incomplete");
			return;
		}
		usage = mt_allocate_usage(hdev, application);
		if (!usage)
			return;

		target = (__s32 **)((char *)usage + offset);
	}

	*target = value;
}


int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
{
	struct hid_report *report;
	int i, j;

	list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) {
		for (i = 0; i < report->maxfield; i++) {
			*field = report->field[i];
			for (j = 0; j < (*field)->maxusage; j++)
				if ((*field)->usage[j].type == type && (*field)->usage[j].code == code)
					return j;
		}
	}
	return -1;
}

static const struct {
	__s32 x;
	__s32 y;
}  hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};

#define map_abs(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_ABS, (c))

#define map_rel(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_REL, (c))

#define map_key(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_KEY, (c))

#define map_led(c)	hid_map_usage(hidinput, usage, &bit, &max, EV_LED, (c))

#define map_abs_clear(c)	hid_map_usage_clear(hidinput, usage, &bit, \
		&max, EV_ABS, (c))

#define map_key_clear(c)	hid_map_usage_clear(hidinput, usage, &bit, \
		&max, EV_KEY, (c))

typedef bool (*hid_usage_cmp_t)(struct hid_usage *usage,
				unsigned int cur_idx, unsigned int val);

#define HID_BATTERY_QUIRK_FEATURE	(1 << 1) /* ask for feature report */

static const struct hid_device_id hid_battery_quirks[] = {
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
			       USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM,
		USB_DEVICE_ID_ELECOM_BM084),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL,
		USB_DEVICE_ID_SYMBOL_SCANNER_3),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK,
		USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD),
	  HID_BATTERY_QUIRK_IGNORE },
	{}
};


__s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
{
	__s32 unit_exponent = field->unit_exponent;
	__s32 logical_extents = field->logical_maximum -
					field->logical_minimum;
	__s32 physical_extents = field->physical_maximum -
					field->physical_minimum;
	__s32 prev;

	/* Check if the extents are sane */
	if (logical_extents <= 0 || physical_extents <= 0)
		return 0;

	/*
	 * Verify and convert units.
	 * See HID specification v1.11 6.2.2.7 Global Items for unit decoding
	 */
	switch (code) {
	case ABS_X:
	case ABS_Y:
	case ABS_Z:
	case ABS_MT_POSITION_X:
	case ABS_MT_POSITION_Y:
	case ABS_MT_TOOL_X:
	case ABS_MT_TOOL_Y:
	case ABS_MT_TOUCH_MAJOR:
	case ABS_MT_TOUCH_MINOR:
		if (field->unit == 0x11) {		/* If centimeters */
			/* Convert to millimeters */
			unit_exponent += 1;
		} else if (field->unit == 0x13) {	/* If inches */
			/* Convert to millimeters */
			prev = physical_extents;
			physical_extents *= 254;
			if (physical_extents < prev)
				return 0;
			unit_exponent -= 1;
		} else {
			return 0;
		}
		break;

	case ABS_RX:
	case ABS_RY:
	case ABS_RZ:
	case ABS_WHEEL:
	case ABS_TILT_X:
	case ABS_TILT_Y:
		if (field->unit == 0x14) {		/* If degrees */
			/* Convert to radians */
			prev = logical_extents;
			logical_extents *= 573;
			if (logical_extents < prev)
				return 0;
			unit_exponent += 1;
		} else if (field->unit != 0x12) {	/* If not radians */
			return 0;
		}
		break;

	default:
		return 0;
	}

	/* Apply negative unit exponent */
	for (; unit_exponent < 0; unit_exponent++) {
		prev = logical_extents;
		logical_extents *= 10;
		if (logical_extents < prev)
			return 0;
	}
	/* Apply positive unit exponent */
	for (; unit_exponent > 0; unit_exponent--) {
		prev = physical_extents;
		physical_extents *= 10;
		if (physical_extents < prev)
			return 0;
	}

	/* Calculate resolution */
	return DIV_ROUND_CLOSEST(logical_extents, physical_extents);
}

static const struct {
	__s32 x;
	__s32 y;
}  hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};

typedef bool (*hid_usage_cmp_t)(struct hid_usage *usage,
				unsigned int cur_idx, unsigned int val);

#define HID_BATTERY_QUIRK_FEATURE	(1 << 1) /* ask for feature report */

#define HID_BATTERY_QUIRK_IGNORE	(1 << 2) /* completely ignore the battery */

static const struct hid_device_id hid_battery_quirks[] = {
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
			       USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
		USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM,
		USB_DEVICE_ID_ELECOM_BM084),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_USB_DEVICE(USB_VENDOR_ID_SYMBOL,
		USB_DEVICE_ID_SYMBOL_SCANNER_3),
	  HID_BATTERY_QUIRK_IGNORE },
	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK,
		USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD),
	  HID_BATTERY_QUIRK_IGNORE },
	{}
};


static void mt_fix_const_field(struct hid_field *field, unsigned int usage)
{
	if (field->usage[0].hid != usage ||
	    !(field->flags & HID_MAIN_ITEM_CONSTANT))
		return;

	field->flags &= ~HID_MAIN_ITEM_CONSTANT;
	field->flags |= HID_MAIN_ITEM_VARIABLE;
}


struct hid_field *hidinput_get_led_field(struct hid_device *hid)
{
	struct hid_report *report;
	struct hid_field *field;
	int i, j;

	list_for_each_entry(report,
			    &hid->report_enum[HID_OUTPUT_REPORT].report_list,
			    list) {
		for (i = 0; i < report->maxfield; i++) {
			field = report->field[i];
			for (j = 0; j < field->maxusage; j++)
				if (field->usage[j].type == EV_LED)
					return field;
		}
	}
	return NULL;
}


static struct hid_input *hidinput_match_application(struct hid_report *report)
{
	struct hid_device *hid = report->device;
	struct hid_input *hidinput;

	list_for_each_entry(hidinput, &hid->inputs, list) {
		if (hidinput->application == report->application)
			return hidinput;
	}

	return NULL;
}