diff options
| author | Ping Cheng <pinglinux@gmail.com> | 2013-07-28 03:38:54 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-08-13 01:31:12 -0400 |
| commit | 401d7d108fc19595f6a7d7dd7d553458155e31fa (patch) | |
| tree | 0f29d91e6ddebfef6b27eb25c2016d538c00b0d1 /drivers | |
| parent | 7bf2a98a436ebc60b5388b1cb5fd3d0fbf78814c (diff) | |
Input: wacom - integrate resolution calculation
Reviewed-by: Jason Gerecke <killertofu@gmail.com>
Tested-by: Jason Gerecke <killertofu@gmail.com>
Signed-off-by: Ping Cheng <pingc@wacom.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/input/tablet/wacom_sys.c | 79 | ||||
| -rw-r--r-- | drivers/input/tablet/wacom_wac.c | 19 |
2 files changed, 41 insertions, 57 deletions
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index aaf23aeae2ea..1ad3e07986b4 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
| @@ -221,39 +221,6 @@ static int wacom_calc_hid_res(int logical_extents, int physical_extents, | |||
| 221 | return logical_extents / physical_extents; | 221 | return logical_extents / physical_extents; |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | /* | ||
| 225 | * The physical dimension specified by the HID descriptor is likely not in | ||
| 226 | * the "100th of a mm" units expected by wacom_calculate_touch_res. This | ||
| 227 | * function adjusts the value of [xy]_phy based on the unit and exponent | ||
| 228 | * provided by the HID descriptor. If an error occurs durring conversion | ||
| 229 | * (e.g. from the unit being left unspecified) [xy]_phy is not modified. | ||
| 230 | */ | ||
| 231 | static void wacom_fix_phy_from_hid(struct wacom_features *features) | ||
| 232 | { | ||
| 233 | int xres = wacom_calc_hid_res(features->x_max, features->x_phy, | ||
| 234 | features->unit, features->unitExpo); | ||
| 235 | int yres = wacom_calc_hid_res(features->y_max, features->y_phy, | ||
| 236 | features->unit, features->unitExpo); | ||
| 237 | |||
| 238 | if (xres > 0 && yres > 0) { | ||
| 239 | features->x_phy = (100 * features->x_max) / xres; | ||
| 240 | features->y_phy = (100 * features->y_max) / yres; | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 244 | /* | ||
| 245 | * Static values for max X/Y and resolution of Pen interface is stored in | ||
| 246 | * features. This mean physical size of active area can be computed. | ||
| 247 | * This is useful to do when Pen and Touch have same active area of tablet. | ||
| 248 | * This means for Touch device, we only need to find max X/Y value and we | ||
| 249 | * have enough information to compute resolution of touch. | ||
| 250 | */ | ||
| 251 | static void wacom_set_phy_from_res(struct wacom_features *features) | ||
| 252 | { | ||
| 253 | features->x_phy = (features->x_max * 100) / features->x_resolution; | ||
| 254 | features->y_phy = (features->y_max * 100) / features->y_resolution; | ||
| 255 | } | ||
| 256 | |||
| 257 | static int wacom_parse_logical_collection(unsigned char *report, | 224 | static int wacom_parse_logical_collection(unsigned char *report, |
| 258 | struct wacom_features *features) | 225 | struct wacom_features *features) |
| 259 | { | 226 | { |
| @@ -265,8 +232,6 @@ static int wacom_parse_logical_collection(unsigned char *report, | |||
| 265 | features->pktlen = WACOM_PKGLEN_BBTOUCH3; | 232 | features->pktlen = WACOM_PKGLEN_BBTOUCH3; |
| 266 | features->device_type = BTN_TOOL_FINGER; | 233 | features->device_type = BTN_TOOL_FINGER; |
| 267 | 234 | ||
| 268 | wacom_set_phy_from_res(features); | ||
| 269 | |||
| 270 | features->x_max = features->y_max = | 235 | features->x_max = features->y_max = |
| 271 | get_unaligned_le16(&report[10]); | 236 | get_unaligned_le16(&report[10]); |
| 272 | 237 | ||
| @@ -640,9 +605,6 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | |||
| 640 | } | 605 | } |
| 641 | } | 606 | } |
| 642 | error = wacom_parse_hid(intf, hid_desc, features); | 607 | error = wacom_parse_hid(intf, hid_desc, features); |
| 643 | if (error) | ||
| 644 | goto out; | ||
| 645 | wacom_fix_phy_from_hid(features); | ||
| 646 | 608 | ||
| 647 | out: | 609 | out: |
| 648 | return error; | 610 | return error; |
| @@ -1228,7 +1190,6 @@ static void wacom_wireless_work(struct work_struct *work) | |||
| 1228 | *((struct wacom_features *)id->driver_info); | 1190 | *((struct wacom_features *)id->driver_info); |
| 1229 | wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3; | 1191 | wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3; |
| 1230 | wacom_wac2->features.device_type = BTN_TOOL_FINGER; | 1192 | wacom_wac2->features.device_type = BTN_TOOL_FINGER; |
| 1231 | wacom_set_phy_from_res(&wacom_wac2->features); | ||
| 1232 | wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096; | 1193 | wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096; |
| 1233 | error = wacom_register_input(wacom2); | 1194 | error = wacom_register_input(wacom2); |
| 1234 | if (error) | 1195 | if (error) |
| @@ -1251,6 +1212,33 @@ fail1: | |||
| 1251 | return; | 1212 | return; |
| 1252 | } | 1213 | } |
| 1253 | 1214 | ||
| 1215 | /* | ||
| 1216 | * Not all devices report physical dimensions from HID. | ||
| 1217 | * Compute the default from hardcoded logical dimension | ||
| 1218 | * and resolution before driver overwrites them. | ||
| 1219 | */ | ||
| 1220 | static void wacom_set_default_phy(struct wacom_features *features) | ||
| 1221 | { | ||
| 1222 | if (features->x_resolution) { | ||
| 1223 | features->x_phy = (features->x_max * 100) / | ||
| 1224 | features->x_resolution; | ||
| 1225 | features->y_phy = (features->y_max * 100) / | ||
| 1226 | features->y_resolution; | ||
| 1227 | } | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | static void wacom_calculate_res(struct wacom_features *features) | ||
| 1231 | { | ||
| 1232 | features->x_resolution = wacom_calc_hid_res(features->x_max, | ||
| 1233 | features->x_phy, | ||
| 1234 | features->unit, | ||
| 1235 | features->unitExpo); | ||
| 1236 | features->y_resolution = wacom_calc_hid_res(features->y_max, | ||
| 1237 | features->y_phy, | ||
| 1238 | features->unit, | ||
| 1239 | features->unitExpo); | ||
| 1240 | } | ||
| 1241 | |||
| 1254 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) | 1242 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) |
| 1255 | { | 1243 | { |
| 1256 | struct usb_device *dev = interface_to_usbdev(intf); | 1244 | 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 | 1285 | ||
| 1298 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | 1286 | endpoint = &intf->cur_altsetting->endpoint[0].desc; |
| 1299 | 1287 | ||
| 1288 | /* set the default size in case we do not get them from hid */ | ||
| 1289 | wacom_set_default_phy(features); | ||
| 1290 | |||
| 1300 | /* Retrieve the physical and logical size for touch devices */ | 1291 | /* Retrieve the physical and logical size for touch devices */ |
| 1301 | error = wacom_retrieve_hid_descriptor(intf, features); | 1292 | error = wacom_retrieve_hid_descriptor(intf, features); |
| 1302 | if (error) | 1293 | if (error) |
| @@ -1312,8 +1303,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
| 1312 | features->device_type = BTN_TOOL_FINGER; | 1303 | features->device_type = BTN_TOOL_FINGER; |
| 1313 | features->pktlen = WACOM_PKGLEN_BBTOUCH3; | 1304 | features->pktlen = WACOM_PKGLEN_BBTOUCH3; |
| 1314 | 1305 | ||
| 1315 | wacom_set_phy_from_res(features); | ||
| 1316 | |||
| 1317 | features->x_max = 4096; | 1306 | features->x_max = 4096; |
| 1318 | features->y_max = 4096; | 1307 | features->y_max = 4096; |
| 1319 | } else { | 1308 | } else { |
| @@ -1323,6 +1312,13 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
| 1323 | 1312 | ||
| 1324 | wacom_setup_device_quirks(features); | 1313 | wacom_setup_device_quirks(features); |
| 1325 | 1314 | ||
| 1315 | /* set unit to "100th of a mm" for devices not reported by HID */ | ||
| 1316 | if (!features->unit) { | ||
| 1317 | features->unit = 0x11; | ||
| 1318 | features->unitExpo = 16 - 3; | ||
| 1319 | } | ||
| 1320 | wacom_calculate_res(features); | ||
| 1321 | |||
| 1326 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); | 1322 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); |
| 1327 | 1323 | ||
| 1328 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { | 1324 | 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 | " Pen" : " Finger", | 1330 | " Pen" : " Finger", |
| 1335 | sizeof(wacom_wac->name)); | 1331 | sizeof(wacom_wac->name)); |
| 1336 | 1332 | ||
| 1337 | |||
| 1338 | other_dev = wacom_get_sibling(dev, features->oVid, features->oPid); | 1333 | other_dev = wacom_get_sibling(dev, features->oVid, features->oPid); |
| 1339 | if (other_dev == NULL || wacom_get_usbdev_data(other_dev) == NULL) | 1334 | if (other_dev == NULL || wacom_get_usbdev_data(other_dev) == NULL) |
| 1340 | other_dev = dev; | 1335 | other_dev = dev; |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 518282da6d85..541197b7b973 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
| @@ -1443,13 +1443,6 @@ void wacom_setup_device_quirks(struct wacom_features *features) | |||
| 1443 | } | 1443 | } |
| 1444 | } | 1444 | } |
| 1445 | 1445 | ||
| 1446 | static unsigned int wacom_calculate_touch_res(unsigned int logical_max, | ||
| 1447 | unsigned int physical_max) | ||
| 1448 | { | ||
| 1449 | /* Touch physical dimensions are in 100th of mm */ | ||
| 1450 | return (logical_max * 100) / physical_max; | ||
| 1451 | } | ||
| 1452 | |||
| 1453 | static void wacom_abs_set_axis(struct input_dev *input_dev, | 1446 | static void wacom_abs_set_axis(struct input_dev *input_dev, |
| 1454 | struct wacom_wac *wacom_wac) | 1447 | struct wacom_wac *wacom_wac) |
| 1455 | { | 1448 | { |
| @@ -1473,11 +1466,9 @@ static void wacom_abs_set_axis(struct input_dev *input_dev, | |||
| 1473 | input_set_abs_params(input_dev, ABS_Y, 0, | 1466 | input_set_abs_params(input_dev, ABS_Y, 0, |
| 1474 | features->y_max, features->y_fuzz, 0); | 1467 | features->y_max, features->y_fuzz, 0); |
| 1475 | input_abs_set_res(input_dev, ABS_X, | 1468 | input_abs_set_res(input_dev, ABS_X, |
| 1476 | wacom_calculate_touch_res(features->x_max, | 1469 | features->x_resolution); |
| 1477 | features->x_phy)); | ||
| 1478 | input_abs_set_res(input_dev, ABS_Y, | 1470 | input_abs_set_res(input_dev, ABS_Y, |
| 1479 | wacom_calculate_touch_res(features->y_max, | 1471 | features->y_resolution); |
| 1480 | features->y_phy)); | ||
| 1481 | } | 1472 | } |
| 1482 | 1473 | ||
| 1483 | if (features->touch_max > 1) { | 1474 | if (features->touch_max > 1) { |
| @@ -1486,11 +1477,9 @@ static void wacom_abs_set_axis(struct input_dev *input_dev, | |||
| 1486 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, | 1477 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, |
| 1487 | features->y_max, features->y_fuzz, 0); | 1478 | features->y_max, features->y_fuzz, 0); |
| 1488 | input_abs_set_res(input_dev, ABS_MT_POSITION_X, | 1479 | input_abs_set_res(input_dev, ABS_MT_POSITION_X, |
| 1489 | wacom_calculate_touch_res(features->x_max, | 1480 | features->x_resolution); |
| 1490 | features->x_phy)); | ||
| 1491 | input_abs_set_res(input_dev, ABS_MT_POSITION_Y, | 1481 | input_abs_set_res(input_dev, ABS_MT_POSITION_Y, |
| 1492 | wacom_calculate_touch_res(features->y_max, | 1482 | features->y_resolution); |
| 1493 | features->y_phy)); | ||
| 1494 | } | 1483 | } |
| 1495 | } | 1484 | } |
| 1496 | } | 1485 | } |
