Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.2-rc5 211 lines 6.3 kB view raw
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/property.h> 13#include <linux/input.h> 14#include <linux/input/mt.h> 15#include <linux/input/touchscreen.h> 16#include <linux/module.h> 17 18static bool touchscreen_get_prop_u32(struct device *dev, 19 const char *property, 20 unsigned int default_value, 21 unsigned int *value) 22{ 23 u32 val; 24 int error; 25 26 error = device_property_read_u32(dev, property, &val); 27 if (error) { 28 *value = default_value; 29 return false; 30 } 31 32 *value = val; 33 return true; 34} 35 36static void touchscreen_set_params(struct input_dev *dev, 37 unsigned long axis, 38 int min, int max, int fuzz) 39{ 40 struct input_absinfo *absinfo; 41 42 if (!test_bit(axis, dev->absbit)) { 43 dev_warn(&dev->dev, 44 "DT specifies parameters but the axis %lu is not set up\n", 45 axis); 46 return; 47 } 48 49 absinfo = &dev->absinfo[axis]; 50 absinfo->minimum = min; 51 absinfo->maximum = max; 52 absinfo->fuzz = fuzz; 53} 54 55/** 56 * touchscreen_parse_properties - parse common touchscreen DT properties 57 * @input: input device that should be parsed 58 * @multitouch: specifies whether parsed properties should be applied to 59 * single-touch or multi-touch axes 60 * @prop: pointer to a struct touchscreen_properties into which to store 61 * axis swap and invert info for use with touchscreen_report_x_y(); 62 * or %NULL 63 * 64 * This function parses common DT properties for touchscreens and setups the 65 * input device accordingly. The function keeps previously set up default 66 * values if no value is specified via DT. 67 */ 68void touchscreen_parse_properties(struct input_dev *input, bool multitouch, 69 struct touchscreen_properties *prop) 70{ 71 struct device *dev = input->dev.parent; 72 struct input_absinfo *absinfo; 73 unsigned int axis; 74 unsigned int minimum, maximum, fuzz; 75 bool data_present; 76 77 input_alloc_absinfo(input); 78 if (!input->absinfo) 79 return; 80 81 axis = multitouch ? ABS_MT_POSITION_X : ABS_X; 82 data_present = touchscreen_get_prop_u32(dev, "touchscreen-min-x", 83 input_abs_get_min(input, axis), 84 &minimum) | 85 touchscreen_get_prop_u32(dev, "touchscreen-size-x", 86 input_abs_get_max(input, 87 axis) + 1, 88 &maximum) | 89 touchscreen_get_prop_u32(dev, "touchscreen-fuzz-x", 90 input_abs_get_fuzz(input, axis), 91 &fuzz); 92 if (data_present) 93 touchscreen_set_params(input, axis, minimum, maximum - 1, fuzz); 94 95 axis = multitouch ? ABS_MT_POSITION_Y : ABS_Y; 96 data_present = touchscreen_get_prop_u32(dev, "touchscreen-min-y", 97 input_abs_get_min(input, axis), 98 &minimum) | 99 touchscreen_get_prop_u32(dev, "touchscreen-size-y", 100 input_abs_get_max(input, 101 axis) + 1, 102 &maximum) | 103 touchscreen_get_prop_u32(dev, "touchscreen-fuzz-y", 104 input_abs_get_fuzz(input, axis), 105 &fuzz); 106 if (data_present) 107 touchscreen_set_params(input, axis, minimum, maximum - 1, fuzz); 108 109 axis = multitouch ? ABS_MT_PRESSURE : ABS_PRESSURE; 110 data_present = touchscreen_get_prop_u32(dev, 111 "touchscreen-max-pressure", 112 input_abs_get_max(input, axis), 113 &maximum) | 114 touchscreen_get_prop_u32(dev, 115 "touchscreen-fuzz-pressure", 116 input_abs_get_fuzz(input, axis), 117 &fuzz); 118 if (data_present) 119 touchscreen_set_params(input, axis, 0, maximum, fuzz); 120 121 if (!prop) 122 return; 123 124 axis = multitouch ? ABS_MT_POSITION_X : ABS_X; 125 126 prop->max_x = input_abs_get_max(input, axis); 127 prop->max_y = input_abs_get_max(input, axis + 1); 128 129 prop->invert_x = 130 device_property_read_bool(dev, "touchscreen-inverted-x"); 131 if (prop->invert_x) { 132 absinfo = &input->absinfo[axis]; 133 absinfo->maximum -= absinfo->minimum; 134 absinfo->minimum = 0; 135 } 136 137 prop->invert_y = 138 device_property_read_bool(dev, "touchscreen-inverted-y"); 139 if (prop->invert_y) { 140 absinfo = &input->absinfo[axis + 1]; 141 absinfo->maximum -= absinfo->minimum; 142 absinfo->minimum = 0; 143 } 144 145 prop->swap_x_y = 146 device_property_read_bool(dev, "touchscreen-swapped-x-y"); 147 if (prop->swap_x_y) 148 swap(input->absinfo[axis], input->absinfo[axis + 1]); 149} 150EXPORT_SYMBOL(touchscreen_parse_properties); 151 152static void 153touchscreen_apply_prop_to_x_y(const struct touchscreen_properties *prop, 154 unsigned int *x, unsigned int *y) 155{ 156 if (prop->invert_x) 157 *x = prop->max_x - *x; 158 159 if (prop->invert_y) 160 *y = prop->max_y - *y; 161 162 if (prop->swap_x_y) 163 swap(*x, *y); 164} 165 166/** 167 * touchscreen_set_mt_pos - Set input_mt_pos coordinates 168 * @pos: input_mt_pos to set coordinates of 169 * @prop: pointer to a struct touchscreen_properties 170 * @x: X coordinate to store in pos 171 * @y: Y coordinate to store in pos 172 * 173 * Adjust the passed in x and y values applying any axis inversion and 174 * swapping requested in the passed in touchscreen_properties and store 175 * the result in a struct input_mt_pos. 176 */ 177void touchscreen_set_mt_pos(struct input_mt_pos *pos, 178 const struct touchscreen_properties *prop, 179 unsigned int x, unsigned int y) 180{ 181 touchscreen_apply_prop_to_x_y(prop, &x, &y); 182 pos->x = x; 183 pos->y = y; 184} 185EXPORT_SYMBOL(touchscreen_set_mt_pos); 186 187/** 188 * touchscreen_report_pos - Report touchscreen coordinates 189 * @input: input_device to report coordinates for 190 * @prop: pointer to a struct touchscreen_properties 191 * @x: X coordinate to report 192 * @y: Y coordinate to report 193 * @multitouch: Report coordinates on single-touch or multi-touch axes 194 * 195 * Adjust the passed in x and y values applying any axis inversion and 196 * swapping requested in the passed in touchscreen_properties and then 197 * report the resulting coordinates on the input_dev's x and y axis. 198 */ 199void touchscreen_report_pos(struct input_dev *input, 200 const struct touchscreen_properties *prop, 201 unsigned int x, unsigned int y, 202 bool multitouch) 203{ 204 touchscreen_apply_prop_to_x_y(prop, &x, &y); 205 input_report_abs(input, multitouch ? ABS_MT_POSITION_X : ABS_X, x); 206 input_report_abs(input, multitouch ? ABS_MT_POSITION_Y : ABS_Y, y); 207} 208EXPORT_SYMBOL(touchscreen_report_pos); 209 210MODULE_LICENSE("GPL v2"); 211MODULE_DESCRIPTION("Device-tree helpers functions for touchscreen devices");