public inbox for linux-input@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] Input: edt-ft5x06 - fix report rate handling by sysfs
@ 2025-09-15 20:16 Dario Binacchi
  2025-09-15 20:16 ` [PATCH 2/2] Input: edt-ft5x06 - rename sysfs attribute report_rate to report_rate_hz Dario Binacchi
  0 siblings, 1 reply; 4+ messages in thread
From: Dario Binacchi @ 2025-09-15 20:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, Al Viro, Dmitry Torokhov,
	Oliver Graute, Wolfram Sang, Yu Jiaoliang, linux-input

In the driver probe, the report-rate-hz value from device tree is written
directly to the M12 controller register, while for the M06 it is divided
by 10 since the controller expects the value in units of 10 Hz. That logic
was missing in the sysfs handling, leading to inconsistent behavior
depending on whether the value came from device tree or sysfs.

This patch makes the report-rate handling consistent by applying the same
logic in both cases. Two dedicated functions, report_rate_hz_{show,store},
were added for the following reasons:

- Avoid modifying the more generic edt_ft5x06_setting_{show,store} and
  thus prevent regressions.
- Properly enforce lower and upper limits for the M06 case. The previous
  version accepted invalid values for M06, since it relied on the M12
  limits.
- Return an error when the property is not supported (e.g. M09), to avoid
  misleading users into thinking the property is handled by the
  controller.

Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
---

 drivers/input/touchscreen/edt-ft5x06.c | 158 +++++++++++++++++++++----
 1 file changed, 135 insertions(+), 23 deletions(-)

diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index bf498bd4dea9..d7a269a0528f 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -516,9 +516,136 @@ static EDT_ATTR(offset_y, S_IWUSR | S_IRUGO, NO_REGISTER, NO_REGISTER,
 /* m06: range 20 to 80, m09: range 0 to 30, m12: range 1 to 255... */
 static EDT_ATTR(threshold, S_IWUSR | S_IRUGO, WORK_REGISTER_THRESHOLD,
 		M09_REGISTER_THRESHOLD, EV_REGISTER_THRESHOLD, 0, 255);
-/* m06: range 3 to 14, m12: range 1 to 255 */
-static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO, WORK_REGISTER_REPORT_RATE,
-		M12_REGISTER_REPORT_RATE, NO_REGISTER, 0, 255);
+
+static int edt_ft5x06_report_rate_get(struct edt_ft5x06_ts_data *tsdata)
+{
+	unsigned int val;
+	int error;
+
+	if (tsdata->reg_addr.reg_report_rate == NO_REGISTER)
+		return -EOPNOTSUPP;
+
+	error = regmap_read(tsdata->regmap, tsdata->reg_addr.reg_report_rate,
+			    &val);
+	if (error)
+		return error;
+
+	if (tsdata->version == EDT_M06)
+		val *= 10;
+
+	if (val != tsdata->report_rate) {
+		dev_warn(&tsdata->client->dev,
+			 "report-rate: read (%d) and stored value (%d) differ\n",
+			 val, tsdata->report_rate);
+		tsdata->report_rate = val;
+	}
+
+	return 0;
+}
+
+static ssize_t report_rate_show(struct device *dev,
+				struct device_attribute *dattr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+	size_t count;
+	int error;
+
+	mutex_lock(&tsdata->mutex);
+
+	if (tsdata->factory_mode) {
+		error = -EIO;
+		goto out;
+	}
+
+	error = edt_ft5x06_report_rate_get(tsdata);
+	if (error) {
+		dev_err(&tsdata->client->dev,
+			"Failed to fetch attribute %s, error %d\n",
+			dattr->attr.name, error);
+		goto out;
+	}
+
+	count = sysfs_emit(buf, "%d\n", tsdata->report_rate);
+out:
+	mutex_unlock(&tsdata->mutex);
+	return error ?: count;
+}
+
+static int edt_ft5x06_report_rate_set(struct edt_ft5x06_ts_data *tsdata,
+				      unsigned int val)
+{
+	if (tsdata->reg_addr.reg_report_rate == NO_REGISTER)
+		return -EOPNOTSUPP;
+
+	if (tsdata->version == EDT_M06)
+		tsdata->report_rate = clamp_val(val, 30, 140);
+	else
+		tsdata->report_rate = clamp_val(val, 1, 255);
+
+	if (val != tsdata->report_rate) {
+		dev_warn(&tsdata->client->dev,
+			 "report-rate %dHz is unsupported, use %dHz\n",
+			 val, tsdata->report_rate);
+		val = tsdata->report_rate;
+	}
+
+	if (tsdata->version == EDT_M06)
+		val /= 10;
+
+	return regmap_write(tsdata->regmap, tsdata->reg_addr.reg_report_rate,
+			    val);
+}
+
+static ssize_t report_rate_store(struct device *dev,
+				 struct device_attribute *dattr,
+				 const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+	unsigned int val;
+	u8 limit_low;
+	u8 limit_high;
+	int error;
+
+	mutex_lock(&tsdata->mutex);
+
+	if (tsdata->factory_mode) {
+		error = -EIO;
+		goto out;
+	}
+
+	error = kstrtouint(buf, 0, &val);
+	if (error)
+		goto out;
+
+	if (tsdata->version == EDT_M06) {
+		limit_low = 30;
+		limit_high = 140;
+	} else {
+		limit_low = 1;
+		limit_high = 255;
+	}
+
+	if (val < limit_low || val > limit_high) {
+		error = -ERANGE;
+		goto out;
+	}
+
+	error = edt_ft5x06_report_rate_set(tsdata, val);
+	if (error) {
+		dev_err(&tsdata->client->dev,
+			"Failed to update attribute %s, error: %d\n",
+			dattr->attr.name, error);
+		goto out;
+	}
+
+out:
+	mutex_unlock(&tsdata->mutex);
+	return error ?: count;
+}
+
+static DEVICE_ATTR_RW(report_rate);
 
 static ssize_t model_show(struct device *dev, struct device_attribute *attr,
 			  char *buf)
@@ -572,7 +699,7 @@ static struct attribute *edt_ft5x06_attrs[] = {
 	&edt_ft5x06_attr_offset_x.dattr.attr,
 	&edt_ft5x06_attr_offset_y.dattr.attr,
 	&edt_ft5x06_attr_threshold.dattr.attr,
-	&edt_ft5x06_attr_report_rate.dattr.attr,
+	&dev_attr_report_rate.attr,
 	&dev_attr_model.attr,
 	&dev_attr_fw_version.attr,
 	&dev_attr_header_errors.attr,
@@ -595,8 +722,7 @@ static void edt_ft5x06_restore_reg_parameters(struct edt_ft5x06_ts_data *tsdata)
 	if (reg_addr->reg_offset_y != NO_REGISTER)
 		regmap_write(regmap, reg_addr->reg_offset_y, tsdata->offset_y);
 	if (reg_addr->reg_report_rate != NO_REGISTER)
-		regmap_write(regmap, reg_addr->reg_report_rate,
-			     tsdata->report_rate);
+		edt_ft5x06_report_rate_set(tsdata, tsdata->report_rate);
 }
 
 #ifdef CONFIG_DEBUG_FS
@@ -1029,8 +1155,8 @@ static void edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data *tsdata)
 	if (reg_addr->reg_offset_y != NO_REGISTER)
 		regmap_read(regmap, reg_addr->reg_offset_y, &tsdata->offset_y);
 	if (reg_addr->reg_report_rate != NO_REGISTER)
-		regmap_read(regmap, reg_addr->reg_report_rate,
-			    &tsdata->report_rate);
+		edt_ft5x06_report_rate_get(tsdata);
+
 	tsdata->num_x = EDT_DEFAULT_NUM_X;
 	if (reg_addr->reg_num_x != NO_REGISTER) {
 		if (!regmap_read(regmap, reg_addr->reg_num_x, &val))
@@ -1289,21 +1415,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
 	if (tsdata->reg_addr.reg_report_rate != NO_REGISTER &&
 	    !device_property_read_u32(&client->dev,
 				      "report-rate-hz", &report_rate)) {
-		if (tsdata->version == EDT_M06)
-			tsdata->report_rate = clamp_val(report_rate, 30, 140);
-		else
-			tsdata->report_rate = clamp_val(report_rate, 1, 255);
-
-		if (report_rate != tsdata->report_rate)
-			dev_warn(&client->dev,
-				 "report-rate %dHz is unsupported, use %dHz\n",
-				 report_rate, tsdata->report_rate);
-
-		if (tsdata->version == EDT_M06)
-			tsdata->report_rate /= 10;
-
-		regmap_write(tsdata->regmap, tsdata->reg_addr.reg_report_rate,
-			     tsdata->report_rate);
+		edt_ft5x06_report_rate_set(tsdata, report_rate);
 	}
 
 	dev_dbg(&client->dev,
-- 
2.43.0

base-commit: f83ec76bf285bea5727f478a68b894f5543ca76e
branch: edt-ft5x06-report-rate

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] Input: edt-ft5x06 - rename sysfs attribute report_rate to report_rate_hz
  2025-09-15 20:16 [PATCH 1/2] Input: edt-ft5x06 - fix report rate handling by sysfs Dario Binacchi
@ 2025-09-15 20:16 ` Dario Binacchi
  2025-09-16  0:38   ` Dmitry Torokhov
  0 siblings, 1 reply; 4+ messages in thread
From: Dario Binacchi @ 2025-09-15 20:16 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-amarula, Dario Binacchi, Al Viro, Dmitry Torokhov,
	Oliver Graute, Wolfram Sang, Yu Jiaoliang, linux-input

The sysfs attribute has been renamed to report_rate_hz to match the
report-rate-hz property from device tree, making it clear that the same
parameter can be set via sysfs or device tree and behaves identically.

Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>

---

 drivers/input/touchscreen/edt-ft5x06.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index d7a269a0528f..c23cf3817664 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -543,8 +543,8 @@ static int edt_ft5x06_report_rate_get(struct edt_ft5x06_ts_data *tsdata)
 	return 0;
 }
 
-static ssize_t report_rate_show(struct device *dev,
-				struct device_attribute *dattr, char *buf)
+static ssize_t report_rate_hz_show(struct device *dev,
+				   struct device_attribute *dattr, char *buf)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
@@ -597,9 +597,9 @@ static int edt_ft5x06_report_rate_set(struct edt_ft5x06_ts_data *tsdata,
 			    val);
 }
 
-static ssize_t report_rate_store(struct device *dev,
-				 struct device_attribute *dattr,
-				 const char *buf, size_t count)
+static ssize_t report_rate_hz_store(struct device *dev,
+				    struct device_attribute *dattr,
+				    const char *buf, size_t count)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
@@ -645,7 +645,7 @@ static ssize_t report_rate_store(struct device *dev,
 	return error ?: count;
 }
 
-static DEVICE_ATTR_RW(report_rate);
+static DEVICE_ATTR_RW(report_rate_hz);
 
 static ssize_t model_show(struct device *dev, struct device_attribute *attr,
 			  char *buf)
@@ -699,7 +699,7 @@ static struct attribute *edt_ft5x06_attrs[] = {
 	&edt_ft5x06_attr_offset_x.dattr.attr,
 	&edt_ft5x06_attr_offset_y.dattr.attr,
 	&edt_ft5x06_attr_threshold.dattr.attr,
-	&dev_attr_report_rate.attr,
+	&dev_attr_report_rate_hz.attr,
 	&dev_attr_model.attr,
 	&dev_attr_fw_version.attr,
 	&dev_attr_header_errors.attr,
-- 
2.43.0

base-commit: f83ec76bf285bea5727f478a68b894f5543ca76e
branch: edt-ft5x06-report-rate

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/2] Input: edt-ft5x06 - rename sysfs attribute report_rate to report_rate_hz
  2025-09-15 20:16 ` [PATCH 2/2] Input: edt-ft5x06 - rename sysfs attribute report_rate to report_rate_hz Dario Binacchi
@ 2025-09-16  0:38   ` Dmitry Torokhov
  2025-09-18 16:04     ` Dario Binacchi
  0 siblings, 1 reply; 4+ messages in thread
From: Dmitry Torokhov @ 2025-09-16  0:38 UTC (permalink / raw)
  To: Dario Binacchi
  Cc: linux-kernel, linux-amarula, Al Viro, Oliver Graute, Wolfram Sang,
	Yu Jiaoliang, linux-input

Hi Dario,

On Mon, Sep 15, 2025 at 10:16:32PM +0200, Dario Binacchi wrote:
> The sysfs attribute has been renamed to report_rate_hz to match the
> report-rate-hz property from device tree, making it clear that the same
> parameter can be set via sysfs or device tree and behaves identically.

No, this attribute was defined since forever and we should avoid
gratuitous renames: they will break existing users. 

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/2] Input: edt-ft5x06 - rename sysfs attribute report_rate to report_rate_hz
  2025-09-16  0:38   ` Dmitry Torokhov
@ 2025-09-18 16:04     ` Dario Binacchi
  0 siblings, 0 replies; 4+ messages in thread
From: Dario Binacchi @ 2025-09-18 16:04 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-kernel, linux-amarula, Al Viro, Oliver Graute, Wolfram Sang,
	Yu Jiaoliang, linux-input

Hello Dmitry,

On Tue, Sep 16, 2025 at 2:38 AM Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
>
> Hi Dario,
>
> On Mon, Sep 15, 2025 at 10:16:32PM +0200, Dario Binacchi wrote:
> > The sysfs attribute has been renamed to report_rate_hz to match the
> > report-rate-hz property from device tree, making it clear that the same
> > parameter can be set via sysfs or device tree and behaves identically.
>
> No, this attribute was defined since forever and we should avoid
> gratuitous renames: they will break existing users.

OK, I understand.
Do you think patch 1/2 is correct?

Thanks and regards,
Dario

>
> Thanks.
>
> --
> Dmitry



-- 

Dario Binacchi

Senior Embedded Linux Developer

dario.binacchi@amarulasolutions.com

__________________________________


Amarula Solutions SRL

Via Le Canevare 30, 31100 Treviso, Veneto, IT

T. +39 042 243 5310
info@amarulasolutions.com

www.amarulasolutions.com

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-09-18 16:05 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-15 20:16 [PATCH 1/2] Input: edt-ft5x06 - fix report rate handling by sysfs Dario Binacchi
2025-09-15 20:16 ` [PATCH 2/2] Input: edt-ft5x06 - rename sysfs attribute report_rate to report_rate_hz Dario Binacchi
2025-09-16  0:38   ` Dmitry Torokhov
2025-09-18 16:04     ` Dario Binacchi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox