All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.