diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-05-01 08:47:44 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-05-01 08:47:44 -0700 | 
| commit | bf61c8840efe60fd8f91446860b63338fb424158 (patch) | |
| tree | 7a71832407a4f0d6346db773343f4c3ae2257b19 /drivers/hid/hid-input.c | |
| parent | 5846115b30f3a881e542c8bfde59a699c1c13740 (diff) | |
| parent | 0c6a61657da78098472fd0eb71cc01f2387fa1bb (diff) | |
| download | olio-linux-3.10-bf61c8840efe60fd8f91446860b63338fb424158.tar.xz olio-linux-3.10-bf61c8840efe60fd8f91446860b63338fb424158.zip  | |
Merge branch 'next' into for-linus
Prepare first set of updates for 3.10 merge window.
Diffstat (limited to 'drivers/hid/hid-input.c')
| -rw-r--r-- | drivers/hid/hid-input.c | 97 | 
1 files changed, 62 insertions, 35 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index d917c0d5368..21b196c394b 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -192,7 +192,6 @@ static int hidinput_setkeycode(struct input_dev *dev,  	return -EINVAL;  } -  /**   * hidinput_calc_abs_res - calculate an absolute axis resolution   * @field: the HID report field to calculate resolution for @@ -208,7 +207,7 @@ static int hidinput_setkeycode(struct input_dev *dev,   * Only exponent 1 length units are processed. Centimeters and inches are   * converted to millimeters. Degrees are converted to radians.   */ -static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) +__s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)  {  	__s32 unit_exponent = field->unit_exponent;  	__s32 logical_extents = field->logical_maximum - @@ -229,17 +228,29 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)  	case ABS_X:  	case ABS_Y:  	case ABS_Z: -		if (field->unit == 0x11) {		/* If centimeters */ +	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 & 0xffffff00)		/* Not a length */ +			return 0; +		unit_exponent += hid_snto32(field->unit >> 4, 4) - 1; +		switch (field->unit & 0xf) { +		case 0x1:				/* If centimeters */  			/* Convert to millimeters */  			unit_exponent += 1; -		} else if (field->unit == 0x13) {	/* If inches */ +			break; +		case 0x3:				/* If inches */  			/* Convert to millimeters */  			prev = physical_extents;  			physical_extents *= 254;  			if (physical_extents < prev)  				return 0;  			unit_exponent -= 1; -		} else { +			break; +		default:  			return 0;  		}  		break; @@ -281,8 +292,9 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)  	}  	/* Calculate resolution */ -	return logical_extents / physical_extents; +	return DIV_ROUND_CLOSEST(logical_extents, physical_extents);  } +EXPORT_SYMBOL_GPL(hidinput_calc_abs_res);  #ifdef CONFIG_HID_BATTERY_STRENGTH  static enum power_supply_property hidinput_battery_props[] = { @@ -299,6 +311,9 @@ static enum power_supply_property hidinput_battery_props[] = {  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_2011_ANSI),  	  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },  	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, @@ -502,9 +517,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel  				if (code <= 0xf)  					code += BTN_JOYSTICK;  				else -					code += BTN_TRIGGER_HAPPY; +					code += BTN_TRIGGER_HAPPY - 0x10; +				break; +		case HID_GD_GAMEPAD: +				if (code <= 0xf) +					code += BTN_GAMEPAD; +				else +					code += BTN_TRIGGER_HAPPY - 0x10;  				break; -		case HID_GD_GAMEPAD:  code += BTN_GAMEPAD; break;  		default:  			switch (field->physical) {  			case HID_GD_MOUSE: @@ -1146,6 +1166,38 @@ static void report_features(struct hid_device *hid)  			}  } +static struct hid_input *hidinput_allocate(struct hid_device *hid) +{ +	struct hid_input *hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); +	struct input_dev *input_dev = input_allocate_device(); +	if (!hidinput || !input_dev) { +		kfree(hidinput); +		input_free_device(input_dev); +		hid_err(hid, "Out of memory during hid input probe\n"); +		return NULL; +	} + +	input_set_drvdata(input_dev, hid); +	input_dev->event = hid->ll_driver->hidinput_input_event; +	input_dev->open = hidinput_open; +	input_dev->close = hidinput_close; +	input_dev->setkeycode = hidinput_setkeycode; +	input_dev->getkeycode = hidinput_getkeycode; + +	input_dev->name = hid->name; +	input_dev->phys = hid->phys; +	input_dev->uniq = hid->uniq; +	input_dev->id.bustype = hid->bus; +	input_dev->id.vendor  = hid->vendor; +	input_dev->id.product = hid->product; +	input_dev->id.version = hid->version; +	input_dev->dev.parent = hid->dev.parent; +	hidinput->input = input_dev; +	list_add_tail(&hidinput->list, &hid->inputs); + +	return hidinput; +} +  /*   * Register the input device; print a message.   * Configure the input layer interface @@ -1157,7 +1209,6 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)  	struct hid_driver *drv = hid->driver;  	struct hid_report *report;  	struct hid_input *hidinput = NULL; -	struct input_dev *input_dev;  	int i, j, k;  	INIT_LIST_HEAD(&hid->inputs); @@ -1188,33 +1239,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)  				continue;  			if (!hidinput) { -				hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); -				input_dev = input_allocate_device(); -				if (!hidinput || !input_dev) { -					kfree(hidinput); -					input_free_device(input_dev); -					hid_err(hid, "Out of memory during hid input probe\n"); +				hidinput = hidinput_allocate(hid); +				if (!hidinput)  					goto out_unwind; -				} - -				input_set_drvdata(input_dev, hid); -				input_dev->event = -					hid->ll_driver->hidinput_input_event; -				input_dev->open = hidinput_open; -				input_dev->close = hidinput_close; -				input_dev->setkeycode = hidinput_setkeycode; -				input_dev->getkeycode = hidinput_getkeycode; - -				input_dev->name = hid->name; -				input_dev->phys = hid->phys; -				input_dev->uniq = hid->uniq; -				input_dev->id.bustype = hid->bus; -				input_dev->id.vendor  = hid->vendor; -				input_dev->id.product = hid->product; -				input_dev->id.version = hid->version; -				input_dev->dev.parent = hid->dev.parent; -				hidinput->input = input_dev; -				list_add_tail(&hidinput->list, &hid->inputs);  			}  			for (i = 0; i < report->maxfield; i++)  |