linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff LaBundy <jeff@labundy.com>
To: Hans de Goede <hdegoede@redhat.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	Bastien Nocera <hadess@hadess.net>,
	Gregor Riepl <onitake@gmail.com>,
	linux-input@vger.kernel.org
Subject: Re: [PATCH resend 1/3] Input: touchscreen - Extend touchscreen_parse_properties() to allow overriding settings with a module option
Date: Wed, 25 Jan 2023 22:41:45 -0600	[thread overview]
Message-ID: <Y9IEiYMo9O1VWoNU@nixie71> (raw)
In-Reply-To: <20230125105416.17406-2-hdegoede@redhat.com>

Hi Hans,

On Wed, Jan 25, 2023 at 11:54:14AM +0100, Hans de Goede wrote:
> On x86/ACPI platforms touchscreens mostly just work without needing any
> device/model specific configuration. But in some cases (mostly with Silead
> and Goodix touchscreens) it is still necessary to manually specify various
> touchscreen-properties on a per model basis.
> 
> This is handled by drivers/platform/x86/touchscreen_dmi.c which contains
> a large list of per-model touchscreen properties which it attaches to the
> (i2c)device before the touchscreen driver's probe() method gets called.
> This means that ATM changing these settings requires recompiling the
> kernel. This makes figuring out what settings/properties a specific
> touchscreen needs very hard for normal users to do.
> 
> Add a new, optional, settings_override string argument to
> touchscreen_parse_properties(), which takes a list of ; separated
> property-name=value pairs, e.g. :
> "touchscreen-size-x=1665;touchscreen-size-y=1140;touchscreen-swapped-x-y".
> 
> This new argument can be used by drivers to implement a module option which
> allows users to easily specify alternative settings for testing.
> 
> The 2 new touchscreen_property_read_u32() and
> touchscreen_property_read_bool() helpers are also exported so that
> drivers can use these to add settings-override support to the code
> for driver-specific properties.
> 
> Reviewed-by: Bastien Nocera <hadess@hadess.net>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---

Thank you for resurrecting this series. Perhaps I can give my own $.02 as
a fellow customer of input.

I can appreciate the hesitancy that was expressed in the past, as this is
not a generic solution and is specific to touch devices. However, I also
agree with your point that extending dts overrides to all properties opens
a can of worms which should not necessarily gate this benign series (i.e.,
"good is not the enemy of great").

Personally I am highly in favor of this series because I myself have had
to support this very situation where a panel arrives 180 degrees from the
expected orientation, and fellow teammates who are not in a position to
quickly spin a build need a means to quickly unblock themselves through a
serial console or other means.

The code itself also LGTM and I verified there were no regressions on one
of my own drivers that expects these properties to come from dts, and so:

Reviewed-by: Jeff LaBundy <jeff@labundy.com>

> Changes in v2:
> - Instead of patching all drivers rename touchscreen_parse_properties()
>   to touchscreen_parse_properties_with_override() and add
>   a static inline wrapper which passes NULL.
> ---
>  drivers/input/touchscreen.c       | 103 ++++++++++++++++++++++++++----
>  include/linux/input/touchscreen.h |  19 +++++-
>  2 files changed, 109 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/input/touchscreen.c b/drivers/input/touchscreen.c
> index 4620e20d0190..3b9505d5468d 100644
> --- a/drivers/input/touchscreen.c
> +++ b/drivers/input/touchscreen.c
> @@ -12,15 +12,80 @@
>  #include <linux/input/touchscreen.h>
>  #include <linux/module.h>
>  
> +static int touchscreen_get_prop_from_settings_string(const char *settings,
> +						     const char *propname,
> +						     bool is_boolean,
> +						     u32 *val_ret)
> +{
> +	char *begin, *end;
> +	u32 val;
> +
> +	if (!settings)
> +		return -ENOENT;
> +
> +	begin = strstr(settings, propname);
> +	if (!begin)
> +		return -ENOENT;
> +
> +	/* begin must be either the begin of settings, or be preceded by a ';' */
> +	if (begin != settings && begin[-1] != ';')
> +		return -EINVAL;
> +
> +	end = begin + strlen(propname);
> +	if (*end != '=') {
> +		if (is_boolean && (*end == '\0' || *end == ';')) {
> +			*val_ret = true;
> +			return 0;
> +		}
> +		return -EINVAL;
> +	}
> +
> +	val = simple_strtoul(end + 1, &end, 0);
> +	if (*end != '\0' && *end != ';')
> +		return -EINVAL;
> +
> +	*val_ret = val;
> +	return 0;
> +}
> +
> +int touchscreen_property_read_u32(struct device *dev, const char *propname,
> +				  const char *settings, u32 *val)
> +{
> +	int error;
> +
> +	error = device_property_read_u32(dev, propname, val);
> +
> +	if (touchscreen_get_prop_from_settings_string(settings, propname,
> +						      false, val) == 0)
> +		error = 0;
> +
> +	return error;
> +}
> +EXPORT_SYMBOL(touchscreen_property_read_u32);
> +
> +bool touchscreen_property_read_bool(struct device *dev, const char *propname,
> +				    const char *settings)
> +{
> +	u32 val;
> +
> +	val = device_property_read_bool(dev, propname);
> +
> +	touchscreen_get_prop_from_settings_string(settings, propname, true, &val);
> +
> +	return val;
> +}
> +EXPORT_SYMBOL(touchscreen_property_read_bool);
> +
>  static bool touchscreen_get_prop_u32(struct device *dev,
>  				     const char *property,
> +				     const char *settings,
>  				     unsigned int default_value,
>  				     unsigned int *value)
>  {
>  	u32 val;
>  	int error;
>  
> -	error = device_property_read_u32(dev, property, &val);
> +	error = touchscreen_property_read_u32(dev, property, settings, &val);
>  	if (error) {
>  		*value = default_value;
>  		return false;
> @@ -50,20 +115,28 @@ static void touchscreen_set_params(struct input_dev *dev,
>  }
>  
>  /**
> - * touchscreen_parse_properties - parse common touchscreen properties
> + * touchscreen_parse_properties_with_settings - parse common touchscreen properties
>   * @input: input device that should be parsed
>   * @multitouch: specifies whether parsed properties should be applied to
>   *	single-touch or multi-touch axes
>   * @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
> + * @settings: string with ; separated name=value pairs overriding
> + *	the device-properties or %NULL.
>   *
>   * This function parses common properties for touchscreens and sets up the
>   * input device accordingly. The function keeps previously set up default
>   * values if no value is specified.
> + *
> + * Callers can optional specify a settings string overriding the
> + * device-properties, this can be used to implement a module option which
> + * allows users to easily specify alternative settings for testing.
>   */
> -void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
> -				  struct touchscreen_properties *prop)
> +void touchscreen_parse_properties_with_settings(struct input_dev *input,
> +						bool multitouch,
> +						struct touchscreen_properties *prop,
> +						const char *settings)
>  {
>  	struct device *dev = input->dev.parent;
>  	struct input_absinfo *absinfo;
> @@ -79,26 +152,32 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
>  	axis_y = multitouch ? ABS_MT_POSITION_Y : ABS_Y;
>  
>  	data_present = touchscreen_get_prop_u32(dev, "touchscreen-min-x",
> +						settings,
>  						input_abs_get_min(input, axis_x),
>  						&minimum);
>  	data_present |= touchscreen_get_prop_u32(dev, "touchscreen-size-x",
> +						 settings,
>  						 input_abs_get_max(input,
>  								   axis_x) + 1,
>  						 &maximum);
>  	data_present |= touchscreen_get_prop_u32(dev, "touchscreen-fuzz-x",
> +						 settings,
>  						 input_abs_get_fuzz(input, axis_x),
>  						 &fuzz);
>  	if (data_present)
>  		touchscreen_set_params(input, axis_x, minimum, maximum - 1, fuzz);
>  
>  	data_present = touchscreen_get_prop_u32(dev, "touchscreen-min-y",
> +						settings,
>  						input_abs_get_min(input, axis_y),
>  						&minimum);
>  	data_present |= touchscreen_get_prop_u32(dev, "touchscreen-size-y",
> +						 settings,
>  						 input_abs_get_max(input,
>  								   axis_y) + 1,
>  						 &maximum);
>  	data_present |= touchscreen_get_prop_u32(dev, "touchscreen-fuzz-y",
> +						 settings,
>  						 input_abs_get_fuzz(input, axis_y),
>  						 &fuzz);
>  	if (data_present)
> @@ -107,10 +186,12 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
>  	axis = multitouch ? ABS_MT_PRESSURE : ABS_PRESSURE;
>  	data_present = touchscreen_get_prop_u32(dev,
>  						"touchscreen-max-pressure",
> +						settings,
>  						input_abs_get_max(input, axis),
>  						&maximum);
>  	data_present |= touchscreen_get_prop_u32(dev,
>  						 "touchscreen-fuzz-pressure",
> +						 settings,
>  						 input_abs_get_fuzz(input, axis),
>  						 &fuzz);
>  	if (data_present)
> @@ -122,28 +203,28 @@ void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
>  	prop->max_x = input_abs_get_max(input, axis_x);
>  	prop->max_y = input_abs_get_max(input, axis_y);
>  
> -	prop->invert_x =
> -		device_property_read_bool(dev, "touchscreen-inverted-x");
> +	prop->invert_x = touchscreen_property_read_bool(dev, "touchscreen-inverted-x",
> +							settings);
>  	if (prop->invert_x) {
>  		absinfo = &input->absinfo[axis_x];
>  		absinfo->maximum -= absinfo->minimum;
>  		absinfo->minimum = 0;
>  	}
>  
> -	prop->invert_y =
> -		device_property_read_bool(dev, "touchscreen-inverted-y");
> +	prop->invert_y = touchscreen_property_read_bool(dev, "touchscreen-inverted-y",
> +							settings);
>  	if (prop->invert_y) {
>  		absinfo = &input->absinfo[axis_y];
>  		absinfo->maximum -= absinfo->minimum;
>  		absinfo->minimum = 0;
>  	}
>  
> -	prop->swap_x_y =
> -		device_property_read_bool(dev, "touchscreen-swapped-x-y");
> +	prop->swap_x_y = touchscreen_property_read_bool(dev, "touchscreen-swapped-x-y",
> +							settings);
>  	if (prop->swap_x_y)
>  		swap(input->absinfo[axis_x], input->absinfo[axis_y]);
>  }
> -EXPORT_SYMBOL(touchscreen_parse_properties);
> +EXPORT_SYMBOL(touchscreen_parse_properties_with_settings);
>  
>  static void
>  touchscreen_apply_prop_to_x_y(const struct touchscreen_properties *prop,
> diff --git a/include/linux/input/touchscreen.h b/include/linux/input/touchscreen.h
> index fe66e2b58f62..0023c6e368ba 100644
> --- a/include/linux/input/touchscreen.h
> +++ b/include/linux/input/touchscreen.h
> @@ -17,8 +17,23 @@ struct touchscreen_properties {
>  	bool swap_x_y;
>  };
>  
> -void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
> -				  struct touchscreen_properties *prop);
> +void touchscreen_parse_properties_with_settings(struct input_dev *input,
> +						bool multitouch,
> +						struct touchscreen_properties *prop,
> +						const char *settings);
> +
> +static inline void touchscreen_parse_properties(struct input_dev *input,
> +						bool multitouch,
> +						struct touchscreen_properties *prop)
> +{
> +	touchscreen_parse_properties_with_settings(input, multitouch, prop, NULL);
> +}
> +
> +int touchscreen_property_read_u32(struct device *dev, const char *propname,
> +				  const char *settings, u32 *val);
> +
> +bool touchscreen_property_read_bool(struct device *dev, const char *propname,
> +				    const char *settings);
>  
>  void touchscreen_set_mt_pos(struct input_mt_pos *pos,
>  			    const struct touchscreen_properties *prop,
> -- 
> 2.39.0
> 

Kind regards,
Jeff LaBundy

  reply	other threads:[~2023-01-26  4:41 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-25 10:54 [PATCH resend 0/3] Input: touchscreen - settings module-param support Hans de Goede
2023-01-25 10:54 ` [PATCH resend 1/3] Input: touchscreen - Extend touchscreen_parse_properties() to allow overriding settings with a module option Hans de Goede
2023-01-26  4:41   ` Jeff LaBundy [this message]
2023-01-25 10:54 ` [PATCH resend 2/3] Input: silead - Add a settings module-parameter Hans de Goede
2023-01-26  4:51   ` Jeff LaBundy
2023-01-26  9:45     ` Hans de Goede
2023-01-26 17:53       ` Gregor Riepl
2023-01-25 10:54 ` [PATCH resend 3/3] Input: goodix " Hans de Goede
2023-01-26  4:53   ` Jeff LaBundy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y9IEiYMo9O1VWoNU@nixie71 \
    --to=jeff@labundy.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=hadess@hadess.net \
    --cc=hdegoede@redhat.com \
    --cc=linux-input@vger.kernel.org \
    --cc=onitake@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).