Skip to content

Commit

Permalink
Input: wacom - introduce wacom_fix_phy_from_hid
Browse files Browse the repository at this point in the history
The Cintiq 24HD touch cannot use wacom_set_phy_from_res to determine
the physical size of the touch sensor since the pen and touch are
on separate USB devices. The physical size is, however, provided in
the HID descriptor, just scaled to a unit we don't use.

This patch introduces the function wacom_fix_phy_from_hid to let
us make use of the unit and exponent data provided by HID to set
the [xy]_phy variables to an appropriate value. This function
relies on a trimmed-down version of hidinput_calc_abs_res from
the hid-input.c.

Signed-off-by: Jason Gerecke <killertofu@gmail.com>
Tested-by: Ping Cheng <pingc@wacom.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
  • Loading branch information
Jason Gerecke authored and Dmitry Torokhov committed Oct 5, 2012
1 parent 9d336da commit 115d5e1
Showing 1 changed file with 71 additions and 0 deletions.
71 changes: 71 additions & 0 deletions drivers/input/tablet/wacom_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,76 @@ static void wacom_close(struct input_dev *dev)
usb_autopm_put_interface(wacom->intf);
}

/*
* Calculate the resolution of the X or Y axis, given appropriate HID data.
* This function is little more than hidinput_calc_abs_res stripped down.
*/
static int wacom_calc_hid_res(int logical_extents, int physical_extents,
unsigned char unit, unsigned char exponent)
{
int prev, unit_exponent;

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

/* Get signed value of nybble-sized twos-compliment exponent */
unit_exponent = exponent;
if (unit_exponent > 7)
unit_exponent -= 16;

/* Convert physical_extents to millimeters */
if (unit == 0x11) { /* If centimeters */
unit_exponent += 1;
} else if (unit == 0x13) { /* If inches */
prev = physical_extents;
physical_extents *= 254;
if (physical_extents < prev)
return 0;
unit_exponent -= 1;
} else {
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 logical_extents / physical_extents;
}

/*
* The physical dimension specified by the HID descriptor is likely not in
* the "100th of a mm" units expected by wacom_calculate_touch_res. This
* function adjusts the value of [xy]_phy based on the unit and exponent
* provided by the HID descriptor. If an error occurs durring conversion
* (e.g. from the unit being left unspecified) [xy]_phy is not modified.
*/
static void wacom_fix_phy_from_hid(struct wacom_features *features)
{
int xres = wacom_calc_hid_res(features->x_max, features->x_phy,
features->unit, features->unitExpo);
int yres = wacom_calc_hid_res(features->y_max, features->y_phy,
features->unit, features->unitExpo);

if (xres > 0 && yres > 0) {
features->x_phy = (100 * features->x_max) / xres;
features->y_phy = (100 * features->y_max) / yres;
}
}

/*
* Static values for max X/Y and resolution of Pen interface is stored in
* features. This mean physical size of active area can be computed.
Expand Down Expand Up @@ -531,6 +601,7 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
error = wacom_parse_hid(intf, hid_desc, features);
if (error)
goto out;
wacom_fix_phy_from_hid(features);

out:
return error;
Expand Down

0 comments on commit 115d5e1

Please sign in to comment.