cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

touchscreen.c (6172B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  Generic helper functions for touchscreens and other two-dimensional
      4 *  pointing devices
      5 *
      6 *  Copyright (c) 2014 Sebastian Reichel <sre@kernel.org>
      7 */
      8
      9#include <linux/property.h>
     10#include <linux/input.h>
     11#include <linux/input/mt.h>
     12#include <linux/input/touchscreen.h>
     13#include <linux/module.h>
     14
     15static bool touchscreen_get_prop_u32(struct device *dev,
     16				     const char *property,
     17				     unsigned int default_value,
     18				     unsigned int *value)
     19{
     20	u32 val;
     21	int error;
     22
     23	error = device_property_read_u32(dev, property, &val);
     24	if (error) {
     25		*value = default_value;
     26		return false;
     27	}
     28
     29	*value = val;
     30	return true;
     31}
     32
     33static void touchscreen_set_params(struct input_dev *dev,
     34				   unsigned long axis,
     35				   int min, int max, int fuzz)
     36{
     37	struct input_absinfo *absinfo;
     38
     39	if (!test_bit(axis, dev->absbit)) {
     40		dev_warn(&dev->dev,
     41			 "Parameters are specified but the axis %lu is not set up\n",
     42			 axis);
     43		return;
     44	}
     45
     46	absinfo = &dev->absinfo[axis];
     47	absinfo->minimum = min;
     48	absinfo->maximum = max;
     49	absinfo->fuzz = fuzz;
     50}
     51
     52/**
     53 * touchscreen_parse_properties - parse common touchscreen properties
     54 * @input: input device that should be parsed
     55 * @multitouch: specifies whether parsed properties should be applied to
     56 *	single-touch or multi-touch axes
     57 * @prop: pointer to a struct touchscreen_properties into which to store
     58 *	axis swap and invert info for use with touchscreen_report_x_y();
     59 *	or %NULL
     60 *
     61 * This function parses common properties for touchscreens and sets up the
     62 * input device accordingly. The function keeps previously set up default
     63 * values if no value is specified.
     64 */
     65void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
     66				  struct touchscreen_properties *prop)
     67{
     68	struct device *dev = input->dev.parent;
     69	struct input_absinfo *absinfo;
     70	unsigned int axis, axis_x, axis_y;
     71	unsigned int minimum, maximum, fuzz;
     72	bool data_present;
     73
     74	input_alloc_absinfo(input);
     75	if (!input->absinfo)
     76		return;
     77
     78	axis_x = multitouch ? ABS_MT_POSITION_X : ABS_X;
     79	axis_y = multitouch ? ABS_MT_POSITION_Y : ABS_Y;
     80
     81	data_present = touchscreen_get_prop_u32(dev, "touchscreen-min-x",
     82						input_abs_get_min(input, axis_x),
     83						&minimum);
     84	data_present |= touchscreen_get_prop_u32(dev, "touchscreen-size-x",
     85						 input_abs_get_max(input,
     86								   axis_x) + 1,
     87						 &maximum);
     88	data_present |= touchscreen_get_prop_u32(dev, "touchscreen-fuzz-x",
     89						 input_abs_get_fuzz(input, axis_x),
     90						 &fuzz);
     91	if (data_present)
     92		touchscreen_set_params(input, axis_x, minimum, maximum - 1, fuzz);
     93
     94	data_present = touchscreen_get_prop_u32(dev, "touchscreen-min-y",
     95						input_abs_get_min(input, axis_y),
     96						&minimum);
     97	data_present |= touchscreen_get_prop_u32(dev, "touchscreen-size-y",
     98						 input_abs_get_max(input,
     99								   axis_y) + 1,
    100						 &maximum);
    101	data_present |= touchscreen_get_prop_u32(dev, "touchscreen-fuzz-y",
    102						 input_abs_get_fuzz(input, axis_y),
    103						 &fuzz);
    104	if (data_present)
    105		touchscreen_set_params(input, axis_y, minimum, maximum - 1, fuzz);
    106
    107	axis = multitouch ? ABS_MT_PRESSURE : ABS_PRESSURE;
    108	data_present = touchscreen_get_prop_u32(dev,
    109						"touchscreen-max-pressure",
    110						input_abs_get_max(input, axis),
    111						&maximum);
    112	data_present |= touchscreen_get_prop_u32(dev,
    113						 "touchscreen-fuzz-pressure",
    114						 input_abs_get_fuzz(input, axis),
    115						 &fuzz);
    116	if (data_present)
    117		touchscreen_set_params(input, axis, 0, maximum, fuzz);
    118
    119	if (!prop)
    120		return;
    121
    122	prop->max_x = input_abs_get_max(input, axis_x);
    123	prop->max_y = input_abs_get_max(input, axis_y);
    124
    125	prop->invert_x =
    126		device_property_read_bool(dev, "touchscreen-inverted-x");
    127	if (prop->invert_x) {
    128		absinfo = &input->absinfo[axis_x];
    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_y];
    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_x], input->absinfo[axis_y]);
    145}
    146EXPORT_SYMBOL(touchscreen_parse_properties);
    147
    148static void
    149touchscreen_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 */
    173void 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}
    181EXPORT_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 */
    195void 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}
    204EXPORT_SYMBOL(touchscreen_report_pos);
    205
    206MODULE_LICENSE("GPL v2");
    207MODULE_DESCRIPTION("Helper functions for touchscreens and other devices");