Commit | Line | Data |
---|---|---|
b98abe52 SR |
1 | /* |
2 | * Generic DT helper functions for touchscreen devices | |
3 | * | |
4 | * Copyright (c) 2014 Sebastian Reichel <sre@kernel.org> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 as | |
8 | * published by the Free Software Foundation. | |
9 | * | |
10 | */ | |
11 | ||
12 | #include <linux/of.h> | |
13 | #include <linux/input.h> | |
0a363a38 | 14 | #include <linux/input/mt.h> |
b98abe52 SR |
15 | #include <linux/input/touchscreen.h> |
16 | ||
7c494375 DT |
17 | static bool touchscreen_get_prop_u32(struct device_node *np, |
18 | const char *property, | |
19 | unsigned int default_value, | |
20 | unsigned int *value) | |
3eea8b5d | 21 | { |
7c494375 DT |
22 | u32 val; |
23 | int error; | |
3eea8b5d | 24 | |
7c494375 DT |
25 | error = of_property_read_u32(np, property, &val); |
26 | if (error) { | |
27 | *value = default_value; | |
28 | return false; | |
29 | } | |
3eea8b5d | 30 | |
7c494375 DT |
31 | *value = val; |
32 | return true; | |
3eea8b5d MR |
33 | } |
34 | ||
35 | static void touchscreen_set_params(struct input_dev *dev, | |
36 | unsigned long axis, | |
37 | int max, int fuzz) | |
38 | { | |
39 | struct input_absinfo *absinfo; | |
40 | ||
41 | if (!test_bit(axis, dev->absbit)) { | |
f61fd21d DT |
42 | dev_warn(&dev->dev, |
43 | "DT specifies parameters but the axis %lu is not set up\n", | |
44 | axis); | |
3eea8b5d MR |
45 | return; |
46 | } | |
47 | ||
48 | absinfo = &dev->absinfo[axis]; | |
49 | absinfo->maximum = max; | |
50 | absinfo->fuzz = fuzz; | |
51 | } | |
52 | ||
b98abe52 SR |
53 | /** |
54 | * touchscreen_parse_of_params - parse common touchscreen DT properties | |
55 | * @dev: device that should be parsed | |
56 | * | |
57 | * This function parses common DT properties for touchscreens and setups the | |
58 | * input device accordingly. The function keeps previously setuped default | |
59 | * values if no value is specified via DT. | |
60 | */ | |
7c494375 | 61 | void touchscreen_parse_of_params(struct input_dev *dev, bool multitouch) |
b98abe52 SR |
62 | { |
63 | struct device_node *np = dev->dev.parent->of_node; | |
7c494375 DT |
64 | unsigned int axis; |
65 | unsigned int maximum, fuzz; | |
66 | bool data_present; | |
b98abe52 SR |
67 | |
68 | input_alloc_absinfo(dev); | |
69 | if (!dev->absinfo) | |
70 | return; | |
71 | ||
7c494375 DT |
72 | axis = multitouch ? ABS_MT_POSITION_X : ABS_X; |
73 | data_present = touchscreen_get_prop_u32(np, "touchscreen-size-x", | |
74 | input_abs_get_max(dev, axis), | |
75 | &maximum) | | |
76 | touchscreen_get_prop_u32(np, "touchscreen-fuzz-x", | |
77 | input_abs_get_fuzz(dev, axis), | |
78 | &fuzz); | |
79 | if (data_present) | |
80 | touchscreen_set_params(dev, axis, maximum, fuzz); | |
b98abe52 | 81 | |
7c494375 DT |
82 | axis = multitouch ? ABS_MT_POSITION_Y : ABS_Y; |
83 | data_present = touchscreen_get_prop_u32(np, "touchscreen-size-y", | |
84 | input_abs_get_max(dev, axis), | |
85 | &maximum) | | |
86 | touchscreen_get_prop_u32(np, "touchscreen-fuzz-y", | |
87 | input_abs_get_fuzz(dev, axis), | |
88 | &fuzz); | |
89 | if (data_present) | |
90 | touchscreen_set_params(dev, axis, maximum, fuzz); | |
b98abe52 | 91 | |
7c494375 DT |
92 | axis = multitouch ? ABS_MT_PRESSURE : ABS_PRESSURE; |
93 | data_present = touchscreen_get_prop_u32(np, "touchscreen-max-pressure", | |
94 | input_abs_get_max(dev, axis), | |
95 | &maximum) | | |
96 | touchscreen_get_prop_u32(np, "touchscreen-fuzz-pressure", | |
97 | input_abs_get_fuzz(dev, axis), | |
98 | &fuzz); | |
99 | if (data_present) | |
100 | touchscreen_set_params(dev, axis, maximum, fuzz); | |
b98abe52 SR |
101 | } |
102 | EXPORT_SYMBOL(touchscreen_parse_of_params); |