2014-05-29 10:51:53 +04:00
/*
* Generic DT helper functions for touchscreen devices
*
* Copyright ( c ) 2014 Sebastian Reichel < sre @ kernel . org >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
*/
2015-07-07 01:18:24 +03:00
# include <linux/property.h>
2014-05-29 10:51:53 +04:00
# include <linux/input.h>
2015-03-22 06:17:57 +03:00
# include <linux/input/mt.h>
2014-05-29 10:51:53 +04:00
# include <linux/input/touchscreen.h>
2018-01-10 22:29:23 +03:00
# include <linux/module.h>
2014-05-29 10:51:53 +04:00
2015-07-07 01:18:24 +03:00
static bool touchscreen_get_prop_u32 ( struct device * dev ,
2015-06-01 20:35:16 +03:00
const char * property ,
unsigned int default_value ,
unsigned int * value )
2015-03-22 06:17:48 +03:00
{
2015-06-01 20:35:16 +03:00
u32 val ;
int error ;
2015-03-22 06:17:48 +03:00
2015-07-07 01:18:24 +03:00
error = device_property_read_u32 ( dev , property , & val ) ;
2015-06-01 20:35:16 +03:00
if ( error ) {
* value = default_value ;
return false ;
}
2015-03-22 06:17:48 +03:00
2015-06-01 20:35:16 +03:00
* value = val ;
return true ;
2015-03-22 06:17:48 +03:00
}
static void touchscreen_set_params ( struct input_dev * dev ,
unsigned long axis ,
2018-10-12 03:04:13 +03:00
int min , int max , int fuzz )
2015-03-22 06:17:48 +03:00
{
struct input_absinfo * absinfo ;
if ( ! test_bit ( axis , dev - > absbit ) ) {
2015-07-07 00:45:25 +03:00
dev_warn ( & dev - > dev ,
" DT specifies parameters but the axis %lu is not set up \n " ,
axis ) ;
2015-03-22 06:17:48 +03:00
return ;
}
absinfo = & dev - > absinfo [ axis ] ;
2018-10-12 03:04:13 +03:00
absinfo - > minimum = min ;
2015-03-22 06:17:48 +03:00
absinfo - > maximum = max ;
absinfo - > fuzz = fuzz ;
}
2014-05-29 10:51:53 +04:00
/**
2015-07-07 01:18:24 +03:00
* touchscreen_parse_properties - parse common touchscreen DT properties
* @ input : input device that should be parsed
* @ multitouch : specifies whether parsed properties should be applied to
* single - touch or multi - touch axes
2016-07-16 00:05:29 +03:00
* @ prop : pointer to a struct touchscreen_properties into which to store
* axis swap and invert info for use with touchscreen_report_x_y ( ) ;
* or % NULL
2014-05-29 10:51:53 +04:00
*
* This function parses common DT properties for touchscreens and setups the
2015-07-07 01:18:24 +03:00
* input device accordingly . The function keeps previously set up default
2014-05-29 10:51:53 +04:00
* values if no value is specified via DT .
*/
2016-07-16 00:05:29 +03:00
void touchscreen_parse_properties ( struct input_dev * input , bool multitouch ,
struct touchscreen_properties * prop )
2014-05-29 10:51:53 +04:00
{
2015-07-07 01:18:24 +03:00
struct device * dev = input - > dev . parent ;
2018-10-12 03:04:13 +03:00
struct input_absinfo * absinfo ;
2015-06-01 20:35:16 +03:00
unsigned int axis ;
2018-10-12 03:04:13 +03:00
unsigned int minimum , maximum , fuzz ;
2015-06-01 20:35:16 +03:00
bool data_present ;
2014-05-29 10:51:53 +04:00
2015-07-07 01:18:24 +03:00
input_alloc_absinfo ( input ) ;
if ( ! input - > absinfo )
2014-05-29 10:51:53 +04:00
return ;
2015-06-01 20:35:16 +03:00
axis = multitouch ? ABS_MT_POSITION_X : ABS_X ;
2018-10-12 03:04:13 +03:00
data_present = touchscreen_get_prop_u32 ( dev , " touchscreen-min-x " ,
input_abs_get_min ( input , axis ) ,
& minimum ) |
touchscreen_get_prop_u32 ( dev , " touchscreen-size-x " ,
2015-07-07 01:18:24 +03:00
input_abs_get_max ( input ,
2015-07-07 00:57:54 +03:00
axis ) + 1 ,
2015-06-01 20:35:16 +03:00
& maximum ) |
2015-07-07 01:18:24 +03:00
touchscreen_get_prop_u32 ( dev , " touchscreen-fuzz-x " ,
input_abs_get_fuzz ( input , axis ) ,
2015-06-01 20:35:16 +03:00
& fuzz ) ;
if ( data_present )
2018-10-12 03:04:13 +03:00
touchscreen_set_params ( input , axis , minimum , maximum - 1 , fuzz ) ;
2014-05-29 10:51:53 +04:00
2015-06-01 20:35:16 +03:00
axis = multitouch ? ABS_MT_POSITION_Y : ABS_Y ;
2018-10-12 03:04:13 +03:00
data_present = touchscreen_get_prop_u32 ( dev , " touchscreen-min-y " ,
input_abs_get_min ( input , axis ) ,
& minimum ) |
touchscreen_get_prop_u32 ( dev , " touchscreen-size-y " ,
2015-07-07 01:18:24 +03:00
input_abs_get_max ( input ,
2015-07-07 00:57:54 +03:00
axis ) + 1 ,
2015-06-01 20:35:16 +03:00
& maximum ) |
2015-07-07 01:18:24 +03:00
touchscreen_get_prop_u32 ( dev , " touchscreen-fuzz-y " ,
input_abs_get_fuzz ( input , axis ) ,
2015-06-01 20:35:16 +03:00
& fuzz ) ;
if ( data_present )
2018-10-12 03:04:13 +03:00
touchscreen_set_params ( input , axis , minimum , maximum - 1 , fuzz ) ;
2014-05-29 10:51:53 +04:00
2015-06-01 20:35:16 +03:00
axis = multitouch ? ABS_MT_PRESSURE : ABS_PRESSURE ;
2015-07-07 01:18:24 +03:00
data_present = touchscreen_get_prop_u32 ( dev ,
" touchscreen-max-pressure " ,
input_abs_get_max ( input , axis ) ,
2015-06-01 20:35:16 +03:00
& maximum ) |
2015-07-07 01:18:24 +03:00
touchscreen_get_prop_u32 ( dev ,
" touchscreen-fuzz-pressure " ,
input_abs_get_fuzz ( input , axis ) ,
2015-06-01 20:35:16 +03:00
& fuzz ) ;
if ( data_present )
2018-10-12 03:04:13 +03:00
touchscreen_set_params ( input , axis , 0 , maximum , fuzz ) ;
2016-07-16 00:05:29 +03:00
if ( ! prop )
return ;
axis = multitouch ? ABS_MT_POSITION_X : ABS_X ;
prop - > max_x = input_abs_get_max ( input , axis ) ;
prop - > max_y = input_abs_get_max ( input , axis + 1 ) ;
2018-10-12 03:04:13 +03:00
2016-07-16 00:05:29 +03:00
prop - > invert_x =
device_property_read_bool ( dev , " touchscreen-inverted-x " ) ;
2018-10-12 03:04:13 +03:00
if ( prop - > invert_x ) {
absinfo = & input - > absinfo [ axis ] ;
absinfo - > maximum - = absinfo - > minimum ;
absinfo - > minimum = 0 ;
}
2016-07-16 00:05:29 +03:00
prop - > invert_y =
device_property_read_bool ( dev , " touchscreen-inverted-y " ) ;
2018-10-12 03:04:13 +03:00
if ( prop - > invert_y ) {
absinfo = & input - > absinfo [ axis + 1 ] ;
absinfo - > maximum - = absinfo - > minimum ;
absinfo - > minimum = 0 ;
}
2016-07-16 00:05:29 +03:00
prop - > swap_x_y =
device_property_read_bool ( dev , " touchscreen-swapped-x-y " ) ;
if ( prop - > swap_x_y )
swap ( input - > absinfo [ axis ] , input - > absinfo [ axis + 1 ] ) ;
2014-05-29 10:51:53 +04:00
}
2015-07-07 01:18:24 +03:00
EXPORT_SYMBOL ( touchscreen_parse_properties ) ;
2016-07-16 00:05:29 +03:00
static void
touchscreen_apply_prop_to_x_y ( const struct touchscreen_properties * prop ,
unsigned int * x , unsigned int * y )
{
if ( prop - > invert_x )
* x = prop - > max_x - * x ;
if ( prop - > invert_y )
* y = prop - > max_y - * y ;
if ( prop - > swap_x_y )
swap ( * x , * y ) ;
}
/**
* touchscreen_set_mt_pos - Set input_mt_pos coordinates
* @ pos : input_mt_pos to set coordinates of
* @ prop : pointer to a struct touchscreen_properties
* @ x : X coordinate to store in pos
* @ y : Y coordinate to store in pos
*
* Adjust the passed in x and y values applying any axis inversion and
* swapping requested in the passed in touchscreen_properties and store
* the result in a struct input_mt_pos .
*/
void touchscreen_set_mt_pos ( struct input_mt_pos * pos ,
const struct touchscreen_properties * prop ,
unsigned int x , unsigned int y )
{
touchscreen_apply_prop_to_x_y ( prop , & x , & y ) ;
pos - > x = x ;
pos - > y = y ;
}
EXPORT_SYMBOL ( touchscreen_set_mt_pos ) ;
/**
* touchscreen_report_pos - Report touchscreen coordinates
* @ input : input_device to report coordinates for
* @ prop : pointer to a struct touchscreen_properties
* @ x : X coordinate to report
* @ y : Y coordinate to report
* @ multitouch : Report coordinates on single - touch or multi - touch axes
*
* Adjust the passed in x and y values applying any axis inversion and
* swapping requested in the passed in touchscreen_properties and then
* report the resulting coordinates on the input_dev ' s x and y axis .
*/
void touchscreen_report_pos ( struct input_dev * input ,
const struct touchscreen_properties * prop ,
unsigned int x , unsigned int y ,
bool multitouch )
{
touchscreen_apply_prop_to_x_y ( prop , & x , & y ) ;
input_report_abs ( input , multitouch ? ABS_MT_POSITION_X : ABS_X , x ) ;
input_report_abs ( input , multitouch ? ABS_MT_POSITION_Y : ABS_Y , y ) ;
}
EXPORT_SYMBOL ( touchscreen_report_pos ) ;
2018-01-10 22:29:23 +03:00
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_DESCRIPTION ( " Device-tree helpers functions for touchscreen devices " ) ;