root/drivers/input/touchscreen/of_touchscreen.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. touchscreen_get_prop_u32
  2. touchscreen_set_params
  3. touchscreen_parse_properties
  4. touchscreen_apply_prop_to_x_y
  5. touchscreen_set_mt_pos
  6. touchscreen_report_pos

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

/* [<][>][^][v][top][bottom][index][help] */