Commit 401d7d10 authored by Ping Cheng's avatar Ping Cheng Committed by Dmitry Torokhov

Input: wacom - integrate resolution calculation

Reviewed-by: default avatarJason Gerecke <killertofu@gmail.com>
Tested-by: default avatarJason Gerecke <killertofu@gmail.com>
Signed-off-by: default avatarPing Cheng <pingc@wacom.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 7bf2a98a
...@@ -221,39 +221,6 @@ static int wacom_calc_hid_res(int logical_extents, int physical_extents, ...@@ -221,39 +221,6 @@ static int wacom_calc_hid_res(int logical_extents, int physical_extents,
return logical_extents / physical_extents; 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.
* This is useful to do when Pen and Touch have same active area of tablet.
* This means for Touch device, we only need to find max X/Y value and we
* have enough information to compute resolution of touch.
*/
static void wacom_set_phy_from_res(struct wacom_features *features)
{
features->x_phy = (features->x_max * 100) / features->x_resolution;
features->y_phy = (features->y_max * 100) / features->y_resolution;
}
static int wacom_parse_logical_collection(unsigned char *report, static int wacom_parse_logical_collection(unsigned char *report,
struct wacom_features *features) struct wacom_features *features)
{ {
...@@ -265,8 +232,6 @@ static int wacom_parse_logical_collection(unsigned char *report, ...@@ -265,8 +232,6 @@ static int wacom_parse_logical_collection(unsigned char *report,
features->pktlen = WACOM_PKGLEN_BBTOUCH3; features->pktlen = WACOM_PKGLEN_BBTOUCH3;
features->device_type = BTN_TOOL_FINGER; features->device_type = BTN_TOOL_FINGER;
wacom_set_phy_from_res(features);
features->x_max = features->y_max = features->x_max = features->y_max =
get_unaligned_le16(&report[10]); get_unaligned_le16(&report[10]);
...@@ -640,9 +605,6 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, ...@@ -640,9 +605,6 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
} }
} }
error = wacom_parse_hid(intf, hid_desc, features); error = wacom_parse_hid(intf, hid_desc, features);
if (error)
goto out;
wacom_fix_phy_from_hid(features);
out: out:
return error; return error;
...@@ -1228,7 +1190,6 @@ static void wacom_wireless_work(struct work_struct *work) ...@@ -1228,7 +1190,6 @@ static void wacom_wireless_work(struct work_struct *work)
*((struct wacom_features *)id->driver_info); *((struct wacom_features *)id->driver_info);
wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3; wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3;
wacom_wac2->features.device_type = BTN_TOOL_FINGER; wacom_wac2->features.device_type = BTN_TOOL_FINGER;
wacom_set_phy_from_res(&wacom_wac2->features);
wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096; wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096;
error = wacom_register_input(wacom2); error = wacom_register_input(wacom2);
if (error) if (error)
...@@ -1251,6 +1212,33 @@ static void wacom_wireless_work(struct work_struct *work) ...@@ -1251,6 +1212,33 @@ static void wacom_wireless_work(struct work_struct *work)
return; return;
} }
/*
* Not all devices report physical dimensions from HID.
* Compute the default from hardcoded logical dimension
* and resolution before driver overwrites them.
*/
static void wacom_set_default_phy(struct wacom_features *features)
{
if (features->x_resolution) {
features->x_phy = (features->x_max * 100) /
features->x_resolution;
features->y_phy = (features->y_max * 100) /
features->y_resolution;
}
}
static void wacom_calculate_res(struct wacom_features *features)
{
features->x_resolution = wacom_calc_hid_res(features->x_max,
features->x_phy,
features->unit,
features->unitExpo);
features->y_resolution = wacom_calc_hid_res(features->y_max,
features->y_phy,
features->unit,
features->unitExpo);
}
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
{ {
struct usb_device *dev = interface_to_usbdev(intf); struct usb_device *dev = interface_to_usbdev(intf);
...@@ -1297,6 +1285,9 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -1297,6 +1285,9 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
endpoint = &intf->cur_altsetting->endpoint[0].desc; endpoint = &intf->cur_altsetting->endpoint[0].desc;
/* set the default size in case we do not get them from hid */
wacom_set_default_phy(features);
/* Retrieve the physical and logical size for touch devices */ /* Retrieve the physical and logical size for touch devices */
error = wacom_retrieve_hid_descriptor(intf, features); error = wacom_retrieve_hid_descriptor(intf, features);
if (error) if (error)
...@@ -1312,8 +1303,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -1312,8 +1303,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
features->device_type = BTN_TOOL_FINGER; features->device_type = BTN_TOOL_FINGER;
features->pktlen = WACOM_PKGLEN_BBTOUCH3; features->pktlen = WACOM_PKGLEN_BBTOUCH3;
wacom_set_phy_from_res(features);
features->x_max = 4096; features->x_max = 4096;
features->y_max = 4096; features->y_max = 4096;
} else { } else {
...@@ -1323,6 +1312,13 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -1323,6 +1312,13 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
wacom_setup_device_quirks(features); wacom_setup_device_quirks(features);
/* set unit to "100th of a mm" for devices not reported by HID */
if (!features->unit) {
features->unit = 0x11;
features->unitExpo = 16 - 3;
}
wacom_calculate_res(features);
strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name));
if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { if (features->quirks & WACOM_QUIRK_MULTI_INPUT) {
...@@ -1334,7 +1330,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -1334,7 +1330,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
" Pen" : " Finger", " Pen" : " Finger",
sizeof(wacom_wac->name)); sizeof(wacom_wac->name));
other_dev = wacom_get_sibling(dev, features->oVid, features->oPid); other_dev = wacom_get_sibling(dev, features->oVid, features->oPid);
if (other_dev == NULL || wacom_get_usbdev_data(other_dev) == NULL) if (other_dev == NULL || wacom_get_usbdev_data(other_dev) == NULL)
other_dev = dev; other_dev = dev;
......
...@@ -1443,13 +1443,6 @@ void wacom_setup_device_quirks(struct wacom_features *features) ...@@ -1443,13 +1443,6 @@ void wacom_setup_device_quirks(struct wacom_features *features)
} }
} }
static unsigned int wacom_calculate_touch_res(unsigned int logical_max,
unsigned int physical_max)
{
/* Touch physical dimensions are in 100th of mm */
return (logical_max * 100) / physical_max;
}
static void wacom_abs_set_axis(struct input_dev *input_dev, static void wacom_abs_set_axis(struct input_dev *input_dev,
struct wacom_wac *wacom_wac) struct wacom_wac *wacom_wac)
{ {
...@@ -1473,11 +1466,9 @@ static void wacom_abs_set_axis(struct input_dev *input_dev, ...@@ -1473,11 +1466,9 @@ static void wacom_abs_set_axis(struct input_dev *input_dev,
input_set_abs_params(input_dev, ABS_Y, 0, input_set_abs_params(input_dev, ABS_Y, 0,
features->y_max, features->y_fuzz, 0); features->y_max, features->y_fuzz, 0);
input_abs_set_res(input_dev, ABS_X, input_abs_set_res(input_dev, ABS_X,
wacom_calculate_touch_res(features->x_max, features->x_resolution);
features->x_phy));
input_abs_set_res(input_dev, ABS_Y, input_abs_set_res(input_dev, ABS_Y,
wacom_calculate_touch_res(features->y_max, features->y_resolution);
features->y_phy));
} }
if (features->touch_max > 1) { if (features->touch_max > 1) {
...@@ -1486,11 +1477,9 @@ static void wacom_abs_set_axis(struct input_dev *input_dev, ...@@ -1486,11 +1477,9 @@ static void wacom_abs_set_axis(struct input_dev *input_dev,
input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,
features->y_max, features->y_fuzz, 0); features->y_max, features->y_fuzz, 0);
input_abs_set_res(input_dev, ABS_MT_POSITION_X, input_abs_set_res(input_dev, ABS_MT_POSITION_X,
wacom_calculate_touch_res(features->x_max, features->x_resolution);
features->x_phy));
input_abs_set_res(input_dev, ABS_MT_POSITION_Y, input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
wacom_calculate_touch_res(features->y_max, features->y_resolution);
features->y_phy));
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment